原文:
軟體開發人員真的了解sql索引嗎(索引使用原則)
前兩篇文章我總結了一些sql資料庫索引的問題,這篇主要來分析下索引的優缼點,以及如何正確使用索引。
索引的優點:這個顯而易見,正確的索引會大大提高資料查詢,對結果進行排序、分組的操作效率。
索引的缺點:優點顯而易見,同樣缺點也是顯而易見:
1:建立索引需要額外的磁碟空間,索引最大一般為表大小的1.2倍左右。
2:在表資料修改時,例如增加,刪除,更新,都需要維護索引表,這是需要系統開銷的。
3:不合理的索引設計非但不能利於系統,反而會使系統效能下降。例如我們在乙個建立有非聚集索引的列上做範圍查詢,此列的索引不會起到任何的優化效果,反而由於資料的修改而需要維護索引表,從而影響了對資料修改的效能。
實際例子:還是拿前兩篇文章的學生表來講吧,要查詢成績在50分以上的學生資訊select * from student where score>50。學生表包含了100000行記錄,而且學分是隨機生成的,這樣從資料量以及資料分布上都有一定的保障。
第一種情況:學生表有索引。
1:存在聚集索引,但聚集索引不在學分上,這裡只分析學分不是聚集索引的情況。
(1):學分上沒有索引。此時sql會通過聚集索引來查詢資料,這點估計大家都會知道。
(2):學分上有索引。這種情況,sql會使用上學分上的索引嗎?這個問題估計不是每個人都能回答正確的。既然學分上有索引,而where中又有此列,理應使用了索引,但實際情況並沒有使用索引。因為出現了範圍查詢,如果乙個索引乙個索引的比較,在效能上比起直接按聚集索引查詢全部資料後再過濾來的差。那學分上的索引什麼時候 sql會優先考慮呢?當score指定為乙個具體值時,就能使用學分索引查詢了。從下圖的sql執行計畫可以得知。
2:不存在聚集索引。
(1):在學分上沒有索引,其它欄位有索引,這種情況就會出現表掃瞄。
(2):在學分上有索引,是否會按照學分上的索引進行查詢呢?由於上面的表資料量也不少,一般會認為sql不會採用表掃瞄,因為會查詢全部記錄,但實際情況表明sql對於範圍查詢也行採用表掃瞄而不是按學生索引查詢。我們也可以強制sql按學分查詢,於是有下面的sql執行計畫比較,我們可以清楚的看出,強制使用學分做為索引查詢比表搜尋的效能要差很多。
第二種情況:學生表沒有索引。這個情況沒有分析的價值。
什麼欄位不適合建立索引?
1:不經常使用的列,這種索引帶來缺點遠大於帶來的優點。
2:邏輯性的字段,例如性別字段等等,匹配的記錄太多,和表掃瞄比起來不相上下。
3:字段內容特別大的字段,例如text等,這會大大增大索引所占用的空間以及索引更新時的速度。
我們說sql在維護索引時要消耗系統資源,那麼sql維護索引時究竟消耗了什麼資源?會產生哪些問題?究竟怎樣才能優化欄位的索引?
第一:當資料頁達到了8k(資料頁最大為8k) 容量,如此時發生插入或更新資料的操作,將導致頁的**。
1、聚集索引的情況下:聚集索引將被插入和更新的行指向特定的頁,該頁由聚集索引關鍵字決定;
2、只有堆的情況下:有空間就可以插入新的行,對行資料的更新需要更多的空間,如果大於了當前頁的可用空間,行就被移到新的頁中,且在原位置留下乙個**指標,指向被移動的新行,如果具有**指標的行又被移動了,那麼原來的指標將重新指向新的位置;
3、堆中有非聚集索引,儘管插入和更新操作,不會發生頁**,但非聚集索引上仍然產生頁**。
總結:無論有無索引,很多資料將保留在老頁面,其它將放入新頁面,並且新頁面可能被分配到任何可用的頁,頻繁頁**,表會產生大量資料碎片,直接造成i/o 效率下降。
引出問題:為什麼資料庫對於varchar最大值設定為8000,而不是10000呢?
答:是由於資料頁大小最大為8k。
第二:針對上述索引可能造成的頁分頁的解決方案,填充因子。
建立索引時,可以為索引指定乙個填充因子,在索引的每個葉級頁面上保留一定百分比的空間,將來資料可以進行擴充和減少頁**。值從0到100的百分比數值,100 時表示將資料頁填滿。不對資料進行更改時(例如唯讀表中)才用此設定,實用價值不大。值越小則資料頁上的空閒空間越大,可以減少在索引增長過程中進行頁**,但需要占用更多的硬碟空間。填充因子也不能設定過小,過小會影響sql的讀取效能,因為填充因子造成資料頁的增多。一般我們公司設定的填充因子是80。
索引是否是一塵不變的?
隨著業務的變化,資料的變化,會發生有些索引的用處可能發生變化,例如:
1:原來主要靠使用者名稱搜尋記錄,現在業務更改為按使用者所在城市搜尋等等,此時我們需要即時變更表索引以適應新業務的變化,即資料和使用模式發生了大幅度變化。
2:系統上線前不合理的索引,隨著資料的增加,缺點越來越明顯,此時需要調整索引。
3:隨著資料的增加,產生了越來越多的頁**,導致索引效能越來越低。
上面的幾種情況,我們就需要選擇重建索引來徹底解決問題。
總結索引使用原則:
1:不要索引資料量不大的表,對於小表來講,表掃瞄的成本並不高。
2:不要設定過多的索引,在沒有聚集索引的表中,最大可以設定249個非聚集索引,過多的索引首先會帶來更大的磁碟空間,而且在資料發生修改時,對索引的維護是特別消耗效能的。
3:合理應用復合索引,有某些情況下可以考慮建立包含所有輸出列的覆蓋索引。
4:對經常使用範圍查詢的字段,可能考慮聚集索引。
5:避免對不常用的列,邏輯性列,大字段列建立索引。
出處:
軟體開發人員真的了解SQL索引嗎 索引原理
上篇文章我粗略的總結了些sql聚集索引與非聚集索引的區別,但看起來好像不太清晰,這篇我通過索引原理來再一次分析下。說明 下面所指的b樹是指平衡樹。索引是為檢索而存在的,就是說索引並不是乙個表必須的。表索引由多個頁面組成,這些頁面一起組成了乙個樹形結構,即我們通常說的b樹,首先來看下表索引的組成部分 ...
軟體開發人員真的了解SQL索引嗎 聚集索引
其實對於非專業的資料庫操作人員來講,例如軟體開發人員,在很大程度上都搞不清楚資料庫索引的一些基本知識,有些是知其一不知其二,或者是知其然不知其所以然。造成這種情況的主要原因我覺的是行業原因,有很多公司都有自己的dba團隊,他們會幫助你優化sql,開發人員即使不懂優化問題也不大,所以開發人員對這方面也...
軟體開發人員的出路
已經從事了一段時間的.net開發,目前在公司裡乙個人負責乙個系統,什麼都得自己去做,只能逼著自己去學啦。分析能力自我感覺還不錯,想以後轉行到系統分析師,請問各位有經驗的大俠,1.由開發人員走哪條路會比較順利的轉到系統分析師?2.目前系統分析師在軟體行業需求怎麼樣?3.系統分析師一般需要具備哪方面的知...