[英]SQL Server Update Where clause performance with clustered index
[英]Index performance with WHERE clause in SQL
我正在閱讀數據庫書中的索引,我想知道我的假設是否正確,即其中帶有非常量表達式的WHERE
子句將不使用索引。 所以如果我有
SELECT * FROM statuses WHERE app_user_id % 10 = 0;
這不會使用在app_user_id上創建的索引。 但
SELECT * FROM statuses WHERE app_user_id = 5;
將使用app_user_id上的索引。
通常(還有其他選擇)數據庫索引是B樹,這意味着您可以對其進行范圍掃描(包括相等性掃描)。
無法通過單次范圍掃描來評估條件app_user_id % 10 = 0
,這就是為什么數據庫可能不會使用索引的原因。
它仍然可以決定以另一種方式使用索引,即進行完全掃描:讀取整個表比讀取整個索引需要更多的時間。 另一方面,在讀取索引之后,您仍然可以返回表,因此最終總成本可能更高。
這由數據庫查詢優化器決定。
一些例子:
select app_user_id from t where app_user_id % 10 = 0
在這里,您根本不需要表,所有必需的數據都在索引中。 數據庫很可能會進行全索引掃描。
select count(*) from t where app_user_id % 10 = 0
相同。 全索引掃描。
select count(*) from t
僅當app_user_id為NOT NULL時,才能使用索引來完成此操作(因為NULL數據不在索引中,至少在Oracle上,至少在單列索引上,數據庫可能會對此進行不同的處理)。
一些數據庫不需要為此做訪問表或索引,它們維護元數據中的行數。
select * from t where app_user_id = 5
這是索引的經典方案。 數據庫可以查看索引樹的一小部分,檢索少量(如果是唯一索引或主索引,則只有一個)行標識符,然后有選擇地從表中獲取它們。
select * from t where app_user_id between 5 and 10
另一個經典的索引案例。 樹中的范圍掃描返回少量要從表中獲取的rowid。
select * from t where app_user_id between 5 and 10 order by app_user_id
由於索引掃描返回有序數據,因此您甚至可以免費獲得排序。
select * from t where app_user_id between 5 and 1000000000
也許在這里您不應該使用索引。 似乎匹配了太多記錄。 在這種情況下,使綁定變量對數據庫隱藏范圍實際上可能是有害的。
select * from t where app_user_id between 5 and 1000000000
order by app_user_id
但是在這里,由於排序將非常昂貴(甚至占用臨時交換磁盤空間),因此按索引順序進行迭代可能很好。 也許。
select * from t where app_user_id % 10 = 0
這很難決定。 我們需要所有列,因此最終查詢需要觸摸表。 問題是是否首先要通過索引。 該查詢返回整個表的大約10%。 對於索引訪問路徑而言,這可能太過高效了。 如果優化器有理由相信查詢返回的數據少於表的10%,則在執行索引掃描后再訪問該表可能會很好。 如果表非常零散(刪除的行很多占用空間),則相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.