根据定义(至少从我所看到的来看)sargable意味着查询能够让查询引擎优化查询使用的执行计划。我试着查了一下答案,但似乎没有太多关于这个主题的内容。问题是,什么能或不能使SQL查询sargable?任何文件都将非常感谢。
参考:Sargable
根据定义(至少从我所看到的来看)sargable意味着查询能够让查询引擎优化查询使用的执行计划。我试着查了一下答案,但似乎没有太多关于这个主题的内容。问题是,什么能或不能使SQL查询sargable?任何文件都将非常感谢。
参考:Sargable
不要这样做:
WHERE Field LIKE '%blah%'
这将导致表/索引扫描,因为LIKE值以通配符开始。
不要这样做:
WHERE FUNCTION(Field) = 'BLAH'
这会导致表/索引扫描。
数据库服务器必须对表中的每一行计算FUNCTION(),然后将其与'BLAH'进行比较。
如果可能的话,倒着做:
WHERE Field = INVERSE_FUNCTION('BLAH')
这将对参数运行一次INVERSE_FUNCTION(),并且仍然允许使用索引。
使查询不可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())
在这个回答中,我假设数据库有足够的覆盖索引。关于这个话题的问题已经够多了。
很多时候,查询的sargability是由相关索引的临界点决定的。临界点定义了将一个表或结果集连接到另一个表或结果集时搜索和扫描索引之间的区别。一次查找当然比扫描整个表快得多,但是当必须查找很多行时,扫描可能更有意义。
因此,当优化器期望一个表的结果行数小于下一个表上可能索引的临界点时,SQL语句更sargable。
你可以在这里找到一篇详细的文章和例子。
For an operation to be considered sargable, it is not sufficient for it to just be able to use an existing index. In the example above, adding a function call against an indexed column in the where clause, would still most likely take some advantage of the defined index. It will "scan" aka retrieve all values from that column (index) and then eliminate the ones that do not match to the filter value provided. It is still not efficient enough for tables with high number of rows. What really defines sargability is the query ability to traverse the b-tree index using the binary search method that relies on half-set elimination for the sorted items array. In SQL, it would be displayed on the execution plan as a "index seek".