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中,它將作為“索引查找”顯示在執行計劃中。
添加回答
舉報