我正在浏览基于SQL Server 2012(现在为SQL Server 2014)的070-461 MS图书,发现此查询部分指出不应使用非聚集索引,因为我们未使用SARGs语法在WHERE
谓词中。
SELECT orderid, custid, orderdate, shipname
FROM Sales.Orders
WHERE DATEDIFF(day, '20060709', orderdate) <= 2
AND DATEDIFF(day, '20060709', orderdate) > 0;
此处的链接支持相同:What makes a SQL statement sargable?
我在SQL Server 2014上测试了完全相同的查询,并且使用非聚集索引(好像它可以存储)确实看到了它
我找不到任何表明SQL Server 2014中已更改的内容,或者SARG会接受列
关于我所缺少的任何想法吗?
这是本书的屏幕截图:
这里是我使用SQL Server 2014的实验室的屏幕截图
答案 0 :(得分:1)
是的,不可保留的查询可以使用非聚集索引。不可扩展的表达式阻止对索引执行查找操作,但是它允许索引扫描。
SQL Server 2014中的基数估计量已更改,我想这就是查询计划更改的原因。
如您在查询计划中看到的那样,该查询仍然不可保留,它完全扫描该索引。如果它是可存储的,或者SQL Server足够聪明,可以将谓词转换为可存储的表达式,则它会寻找索引。
SQL Server可以通过两种不同的方式解决查询:
方法1:
方法2:
因此,方法1需要25个逻辑读取,而方法2需要14个逻辑读取。方法2比方法1更有效。
但是,仅当与谓词匹配的行数足够小且索引大小差异足够大时,方法2才比方法1更有效。例如,如果有10个匹配的行,则需要6 + 10 * 4 = 46,这比方法1所需的逻辑读取还要多。
如果SQL Server 估计匹配行的数量足够小并且非聚集索引比聚集索引更小,SQL Server将选择方法2。
SQL Server更改了SQL Server 2014上的基数估计量,因此这可能是查询计划更改的原因。