根据定义(至少从我所看到的来看)sargable意味着查询能够让查询引擎优化查询使用的执行计划。我试着查了一下答案,但似乎没有太多关于这个主题的内容。问题是,什么能或不能使SQL查询sargable?任何文件都将非常感谢。
供参考:Sargable
不要这样做:
WHERE Field LIKE '%blah%'
这将导致表/索引扫描,因为LIKE值以通配符开始。
WHERE FUNCTION(Field) = 'BLAH'
这会导致表/索引扫描。
数据库服务器必须对表中的每一行计算FUNCTION(),然后将其与'BLAH'进行比较。
如果可能的话,倒着做:
WHERE Field = INVERSE_FUNCTION('BLAH')
这将对参数运行一次INVERSE_FUNCTION(),并且仍然允许使用索引。
使查询non-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。
你可以找到一个详细的帖子和例子在这里。