如何解决索引合并查找
| 我有一个带有列[MyColumn] NVarchar(50)的表[MyTable]。现在,在运行以下两个查询时,我在此列上具有非聚集索引:SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = @MyColumn
SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = COALESCE(@MyColumn,M.[MyColumn] )
我注意到第一个查询使用索引查找(非群集),第二个查询使用索引扫描(非群集)。我可以知道如何结合使用索引搜索和isull吗?
解决方法
我可以知道如何利用
索引合并还是isull?
也许不是您问题的答案,但是您可以有两个不同的查询。一种用于
@MyColumn is null
的情况,另一种用于您要在where子句中使用@MyColumn
的情况。
IF @MyColumn IS NULL
BEGIN
SELECT 1
FROM [MyTable] M
END
ELSE
BEGIN
SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = @MyColumn
END
, 这并不容易,因为正如Alex指出的那样,使用这些功能会强制进行扫描,因为优化器知道需要检查每一行。
您可以做的就是为函数的结果创建一个计算列,并对该列进行索引。
寻求并没有真正漂亮的方法。
编辑:
在重读问题时,除非您重新考虑逻辑,否则这可能不是您的选择。您正在将变量集成到函数中,并且绝对没有办法对其进行索引。
编辑2:
代替您当前的逻辑,请尝试如下操作:
...
WHERE (M.[MyColumn] = @MyColumn
OR @MyColumn IS NULL)
, 在where子句中使用诸如COALESCE
或ISNULL
之类的函数来请求服务器搜索那些函数的结果-在结果集中的每一行都执行它们之前,这些结果是未知的,因此它无法利用指数。
要充分利用索引,请不要使用WHERE子句中的函数,而应使用标准条件对其进行修改,例如WHERE MyColumn = @MyColumn OR @MyColumn IS NULL
, 我猜您将在一个更复杂的查询中使用此查询,可能使用EXISTS
:
EXISTS
( SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = COALESCE(@MyColumn,M.[MyColumn] )
)
尝试以下方法:
EXISTS
( SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = @MyColumn
)
OR EXISTS
( SELECT 1
FROM [MyTable] M
WHERE @MyColumn IS NULL
)
或者这个:
CASE WHEN @MyColumn IS NULL
THEN 1
ELSE
( SELECT 1
FROM [MyTable] M
WHERE M.[MyColumn] = @MyColumn
)
END
, 在带有合并子句的查询中,优化器知道\“ MyColumn \”是一个值范围,因此它将决定对索引使用扫描。当传入非空变量时,使用查找的唯一方法是对两个存储的proc进行编码,并通过对该变量进行逻辑测试来调用适当的变量。
如果您的情况像示例一样简单,并且希望在变量不为NULL时使用索引查找,则应将查询编码为:
If @MyColumn is NULL
Begin
EXEC MyStoredProcWithMyColumn=Mycolumn
END
ELSE
Begin
EXEC MyStoredProcWithMyColumn=Variable @MyColumn
END
创建两个存储过程后,一个将使用带有变量的where子句返回数据,而另一个将其列的where分组返回等于自身的位置。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。