3 回答
TA贡献1786条经验 获得超11个赞
使查询不可搜索的最常见的事情是在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())
TA贡献1995条经验 获得超2个赞
不要这样做:
WHERE Field LIKE '%blah%'
这会导致表/索引扫描,因为LIKE值以通配符开头。
不要这样做:
WHERE FUNCTION(Field) = 'BLAH'
这会导致表/索引扫描。
数据库服务器必须针对表中的每一行计算FUNCTION(),然后将其与“BLAH”进行比较。
如果可能的话,反过来做:
WHERE Field = INVERSE_FUNCTION('BLAH')
这将对参数运行一次INVERSE_FUNCTION()并仍然允许使用索引。
TA贡献1796条经验 获得超4个赞
对于被认为是可攻击的操作,仅仅能够使用现有索引是不够的。在上面的示例中,对where子句中的索引列添加函数调用仍然很可能会利用已定义的索引。它将“扫描”也从该列(索引)中检索所有值,然后消除与提供的过滤器值不匹配的值。对于行数较多的表,它仍然不够高效。真正定义sargability的是使用二进制搜索方法遍历b-tree索引的查询能力,该方法依赖于已排序项目数组的半集消除。在SQL中,它将作为“索引查找”显示在执行计划中。
添加回答
举报