當前位置:成語大全網 - 古籍善本 - 索引的使用規則和設計註意事項

索引的使用規則和設計註意事項

當我們建立了壹個聯合索引後,如何編寫我們的SQL語句讓他的查詢使用我們建立的索引呢?

索引最基本的規則是等價匹配,即where條件中的查詢條件字段與聯合索引中的完全相同,並且都是基於相等進行匹配的。

匹配最左邊的列。如果我們設計的索引是index (class _ name,student _ name,course _ name),那麽查詢where的SQL語句就不必基於三個字段,只需基於字段最左邊的部分即可。

例如:select * from student _ score其中class_name =' xx ',student_name =' xx ',索引中只能搜索class_name和student_name,可以查詢壹個學生所有科目的成績。

但如果妳的SQL是select * from where course _ name = ' xx ',就不能去索引,因為在B+樹中,必須先按class_name搜索,再按student_name搜索,不能跳過前兩個字段。

最左邊的匹配規則,如果要用like語法,比如select * from student _ socre where class _ name like ' 1% ',也可以索引。

因為妳的聯合索引的B+樹是按class_name排序的,如果妳把class_name最左邊的前綴給定為1,然後給它壹個模糊匹配符號,也可以基於索引進行搜索。

但是如果妳的where條件是class_name like '% class ',左邊是模糊查詢,就不能用索引了。

範圍搜索,如果您查詢的SQL是:select * from student _ score where Class _ name > Class 1 ' and Class _ name

因為我們索引底部的數據頁都是由雙向鏈表按順序組成的,所以妳可以先找到‘1類’對應的數據頁,再找到‘5類’對應的數據頁。兩個數據頁中間的數據頁都在妳的範圍內!

ORDER BY如何使用索引?

假設您有壹個查詢:select * from table where XXX = XXX order by XXX。似乎應該基於WHERE語句通過索引快速篩選出壹波數據,然後放入內存或臨時磁盤文件,再通過排序算法按某個字段排序,最後返回排序後的數據。

如果這樣的話,肯定會慢壹些,所以最好不要這樣做。

尤其是像select * from table order by xx 1,xx2,xx3limit 10這樣的SQL語句,在找出壹批數據後,按多個字段排序,最後返回第壹個10的數據。類似的語句經常出現在分頁SQL語句中。

在這種情況下,我們可以建立壹個聯合指數INDEX(xx1,xx2,xx3)。此時索引中的數據默認按照xx1,xx2,xx3排序,不需要找出壹批數據,在內存或磁盤中做復雜的排序工作。

直接獲取10數據的主鍵,回到聚簇索引中的表,查詢剩下的字段。

所以在妳的SQL中,最好是按照聯合索引的字段順序進行排序,這樣就可以直接使用聯合索引的數據順序,直接按照索引樹中字段值的順序來獲取數據。

GROUP BY如何使用索引?

假設您有這樣壹個查詢:select count(*)from table group by xx statement。看來妳必須先找出壹批數據,然後把這些數據放到壹個臨時磁盤文件中並加上壹些內存,按照指定字段的值把它們分成組,然後對每組執行壹個聚合函數。這個性能也是極差的,因為畢竟涉及到大量的磁盤交互。

在索引樹中,數據都是根據壹些指定的字段進行排序的。實際上,具有相同字段值的數據都在壹起。假設如果拿索引來進行分組然後聚合,性能肯定比臨時磁盤文件好很多。

因此,group by之後的字段也應該根據聯合索引中最左邊的字段按順序排列,以便索引可以用於提取數據組。

Order by和group by使用相同的索引原則,並且都依賴於索引數據的順序。

索引設計中的註意事項

壹般建立索引,盡量使用那些區分度大的字段,充分發揮B+樹快速二分搜索法的優勢。

什麽是更大程度的歧視?

也就是說,妳的表中壹列的不同值越多,區別越大,不同值越少,區別越小。比如順序表中每個數據的順序號和順序號都不壹樣,所以它的區分度就大,而性別字段壹般是男、女、未知,區分度就比較小。

如果妳為壹個區分度很小的領域建立壹個指數,妳會找出很多數據,意義不大。

盡量為字段類型小的列設計索引,比如tinyint,因為他的字段類型小,意味著字段本身的值占用的磁盤空間少,妳搜索的時候性能會更好。

如果您的字段是name VARCHAR(255),您可以索引字段的前20個字符,也就是說,將該字段的每個值的前20個字符放在索引樹中。

但此時,不能按名稱順序使用索引,按名稱分組也是如此。因為索引樹只包含前20個字符。

函數和索引

假設妳已經設計了索引,但是它是寫在妳的SQL中的,其中sum(xxx)=xx,並且妳已經為妳的索引中的字段xxx使用了該函數,妳還能使用該索引嗎?

不能,所以盡量不要讓查詢語句中的字段有任何功能。

現在設計壹個指數需要註意的點都做完了。其實就是設計好壹個索引,讓妳的查詢語句可以使用索引。同時註意字段基數、前綴索引和索引列函數的問題,讓妳的查詢盡量使用索引,不要因為某些原因使用索引。

因為索引本身占用存儲空間,所以在添加、刪除、修改的時候也要維護。壹般來說,索引不應該設計太多的索引。建議兩個或三個聯合索引應該覆蓋您的表的所有查詢。

疊加索引

通常,輔助索引的葉節點只包含索引中的幾個字段值和主鍵值。如果要查詢表中的很多字段,需要回表查詢,即先獲取二級索引中的主鍵id,然後回表根據主鍵id找出所有字段。這個性能其實並不高。

如果所有字段都只能在二級索引中找到就完美了,還會引入疊加索引的概念。

覆蓋索引不是索引,而是基於索引的查詢。

假設您有壹個查詢語句,例如select xx 1,xx2,xx3 from table order by xx 1,xx2,xx3。在這種情況下,只需要聯合索引中幾個字段的值,所以實際上只需要掃描聯合索引的索引樹,不需要回表去找聚集索引中的其他字段。

妳要查的Xx1,xx2,xx3可以從二級索引中提取,不需要在簇索引中查。這是疊加索引。

所以妳最好在妳的SQL中只指定幾個字段,不要總是做壹個select *來取出所有的字段,甚至最好是直接去覆蓋索引而不是回聚簇索引。

即使有必要將表返回到聚集索引,也應該用limit和where等語句限制將表返回到聚集索引的次數,盡可能從二級索引中篩選出最少的數據,然後將表返回到聚集索引,這樣性能會更好。