什么使得SQL语句变得可行?
根据定义(至less从我看到的)sargable意味着查询能够使查询引擎优化查询使用的执行计划。 我已经试过寻找答案,但似乎没有太多的主题。 所以问题是,什么做或不做一个SQL查询sargable? 任何文件将不胜感激。
供参考: Sargable
使得查询不可变的最常见的事情是在where子句中的一个函数中包含一个字段:
SELECT ... FROM ... WHERE Year(myDate) = 2008
即使存在,SQL优化程序也不能在myDate上使用索引。 它将从字面上必须为表格的每一行评估这个函数。 更好的使用:
WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'
其他一些例子:
Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones' Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL)) Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford' Fixed: Select ... WHERE DealerName Like 'Ford%' Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30 Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate())
不要这样做:
WHERE Field LIKE '%blah%'
这会导致表/索引扫描,因为LIKE值以通配符开始。
不要这样做:
WHERE FUNCTION(Field) = 'BLAH'
这会导致表/索引扫描。
数据库服务器将必须针对表中的每一行评估FUNCTION(),然后将其与“BLAH”进行比较。
如果可能的话,做相反的事情:
WHERE Field = INVERSE_FUNCTION('BLAH')
这将对参数运行INVERSE_FUNCTION()一次,仍然允许使用索引。
在这个答案中,我假设数据库有足够的覆盖索引。 关于这个话题有足够的问题。
很多时候查询的可search性是由相关索引的临界点决定的。 临界点定义了在将一个表或结果集合到另一个表上时寻求和扫描索引之间的区别。 一次search当然比扫描整个表快得多,但是当你需要search很多行时,扫描可能更有意义。
因此,当优化程序期望一个表的结果行数小于下一个表上可能的索引的临界点时,SQL语句更加可靠。
你可以在这里find一个详细的post和例子。
对于被认为是可操作的操作,仅仅能够使用现有的索引是不够的。 在上面的例子中,在where子句中添加一个针对索引列的函数调用仍然最有可能占用已定义索引的一些优势。 它将“扫描”aka检索该列(索引)中的所有值,然后消除与提供的filter值不匹配的值。 对于具有大量行的表,它仍然不够高效。 真正定义sargability的是使用二分search方法遍历b-tree索引的查询能力,该方法依赖于sorting项目数组的半集消除。 在SQL中,它将作为“索引查找”显示在执行计划中。