导致聚集索引扫描的日期参数

编程入门 行业动态 更新时间:2024-10-27 10:20:28
本文介绍了导致聚集索引扫描的日期参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有以下查询

DECLARE @StartDate DATE = '2017-09-22' DECLARE @EndDate DATE = '2017-09-23' SELECT a.col1, a.col2, b.col1, b.col2, b.col3, a.col3 FROM TableA a JOIN TableB b ON b.pred = a.pred WHERE b.col2 > @StartDate AND b.col2 < @EndDate

当我运行它并检查实际执行计划时,我可以看到成本最高的操作符是聚集索引扫描(索引在 a.pred 上)

When I run this and inspect the actual execution plan, I can see that the most costly operator is a clustered index scan (The index is on a.pred)

但是,如果我按如下方式更改查询

However, if I change the query as follows

SELECT a.col1, a.col2, b.col1, b.col2, b.col3, a.col3 FROM TableA a JOIN TableB b ON b.pred = a.pred WHERE b.col2 > '2017-09-22' AND b.col2 < '2017-09-23'

取消了索引扫描并使用了索引查找.

The index scan is eliminated and an index seek is used.

谁能解释一下这是为什么?在我看来,这与变量中的值可以是任何值这一事实有关,因此 SQL 不知道如何计划执行.

Can someone explain why this is? In my mind, this is something to do with the fact that the value in the variable could be anything so SQL doesn't know how plan the execution.

有什么办法可以消除表扫描但仍然使用变量?(PS,这将被转换为一个以@StartDate和@EndDate为参数的存储过程)

Is there any way I can eliminate the table scan but still have use of the variable? (PS, this will be converted to a stored procedure which takes @StartDate and @EndDate as parameters)

编辑

col2 是 DATETIME,但是,如果我将变量设置为 DATETIME,问题仍然存在

col2 is DATETIME, however, if I make my variable DATETIME the problem still persists

推荐答案

SQL 使计划可重用于变量.

SQL makes plans reusable for variables.

当您使用变量时 - 它会在不知道您将传递的实际值的情况下编译查询.即使在这个 sql batch 中,值也是已知的.但是它不需要为另一组传递参数重新编译查询.

When you use variables - it compiles query without knowing actual values you'll pass. Even in this sql batch values are known. But it won't need to recompile query for another set of passing arguments.

因此,如果您对值进行硬编码 - DB 会编译它选择针对这些特定值优化的计划(例如,它猜测通过日期检查的预期行数).它至少不会比使用变量更糟糕".但是 DB 需要为另一组硬编码值重新编译它(因为查询的文本已更改),这需要时间和垃圾 compiled query cache 存储取代其他有用的查询.

So if you hardcode values - DB compiles it chosing the plan optimized for these particular values (e.g., it guesses expected number of rows passed date check). It'd be 'at least not worse' than when you use variables. But DB needs to recompile it for another set of hardcoded values (because text of the query is changed), which takes time and litters compiled query cache storage superseding the other useful queries.

截至:

有什么办法可以消除表扫描但仍然使用变量?(PS,这将被转换为一个以@StartDate和@EndDate为参数的存储过程)

Is there any way I can eliminate the table scan but still have use of the variable? (PS, this will be converted to a stored procedure which takes @StartDate and @EndDate as parameters)

我认为 b.col2 上的非聚集索引可能是解决方案.此索引的键也可能包含 b.pred 作为代理键的一部分或包含 (with include(pred)).

I think non-clustered index on b.col2 maybe be the solution. The key of this index may also contain b.pred as a part of surrogate key or as including (with include(pred)).

更多推荐

导致聚集索引扫描的日期参数

本文发布于:2023-10-15 02:24:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1492975.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:索引   参数   日期

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!