一、索引的概念
索引就是加快檢索表中資料的方法。資料庫的索引類似於書籍的索引。在書籍中,索引允許使用者不必翻閱完整個書就能迅速地找到所需要的資訊。在資料庫中,索引也允許資料庫程式迅速地找到表中的資料,而不必掃描整個資料庫。
二、索引的特點
1.索引可以加快資料庫的檢索速度
2.索引降低了資料庫插入、修改、刪除等維護任務的速度
3.索引建立在表上,不能建立在視圖上
4.索引既可以直接建立,也可以間接建立
5.可以在最佳化隱藏中,使用索引
6.使用查詢處理器執行SQL語句,在一個表上,一次只能使用一個索引
7.其他
三、索引的優點
1、選擇索引的資料類型
MySQL支援很多資料類型,選擇合適的資料類型儲存資料對效能有很大的影響。通常來說,可以遵循以下一些指導原則:
(1)越小的資料類型通常更好:越小的資料類型通常在磁碟、記憶體和CPU緩衝中都需要更少的空間,處理起來更快。
(2)簡單的資料類型更好:整型資料比起字元,處理開銷更小,因為字串的比較更複雜。在MySQL中,應該用內建的日期和時間資料類型,而不是用字串來儲存時間;以及用整數資料型別儲存IP地址。
(3)盡量避免NULL:應該指定列為NOT NULL,除非你想儲存NULL。在MySQL中,含有空值的列很難進行查詢最佳化,因為它們使得索引、索引的統計資訊以及比較運算更加複雜。你應該用0、一個特殊的值或者一個空串代替空值。
1.1、選擇標識符
選擇合適的標識符是非常重要的。選擇時不僅應該考慮儲存類型,而且應該考慮MySQL是怎樣進行運算和比較的。一旦選定資料類型,應該保證所有相關的表都使用相同的資料類型。
(1) 整型:通常是作為標識符的最好選擇,因為可以更快的處理,而且可以設定為AUTO_INCREMENT。
(2) 字串:盡量避免使用字串作為標識符,它們消耗更好的空間,處理起來也較慢。而且,通常來說,字串都是隨機的,所以它們在索引中的位置也是隨機的,這會導致頁面分裂、隨機訪問磁碟,聚簇索引分裂(對於使用聚簇索引的儲存引擎)。
2、索引入門
對於任何DBMS,索引都是進行最佳化的最主要的因素。對於少量的資料,沒有合適的索引影響不是很大,但是,當隨著資料量的增加,效能會急劇下降。
如果對多列進行索引(複合式索引),列的順序非常重要,MySQL僅能對索引最左邊的首碼進行有效尋找。例如:
假設存在複合式索引it1c1c2(c1,c2),查詢語句select * from t1 where c1=1 and c2=2能夠使用該索引。查詢語句select * from t1 where c1=1也能夠使用該索引。但是,查詢語句select * from t1 where c2=2不能夠使用該索引,因為沒有複合式索引的引導列,即,要想使用c2列進行尋找,必需出現c1等於某值。
2.1、索引的類型
索引是在儲存引擎中實現的,而不是在伺服器層中實現的。所以,每種儲存引擎的索引都不一定完全相同,並不是所有的儲存引擎都支援所有的索引類型。
2.1.1、B-Tree索引
假設有如下一個表:
CREATE TABLE People (
last_name varchar(50) not null,
first_name varchar(50) not null,
dob date not null,
gender enum('m', 'f') not null,
key(last_name, first_name, dob)
);
四、索引的缺點
1.建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加
2.索引需要佔物理空間,除了資料表占資料空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大
3.當對錶中的資料進行增加、刪除和修改的時候,索引也要動態維護,降低了資料的維護速度
五、索引分類
1.直接建立索引和間接建立索引
直接建立索引: CREATE INDEX mycolumn_index ON mytable (myclumn)
間接建立索引:定義主鍵約束或者唯一性鍵約束,可以間接建立索引
2.普通索引和唯一性索引
普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
唯一性索引:保證在索引列中的全部資料是唯一的,對聚簇索引和非聚簇索引都可以使用
CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
3.單個索引和複合索引
單個索引:即非複合索引
複合索引:又叫複合式索引,在索引建立語句中同時包含多個欄位名,最多16個欄位
CREATE INDEX name_index ON username(firstname,lastname)
4.聚簇索引和非聚簇索引(叢集索引,群集索引)
聚簇索引:物理索引,與基表的物理順序相同,資料值的順序總是按照順序排列
CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH
ALLOW_DUP_ROW(允許有重複記錄的聚簇索引)
非聚簇索引:CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)
六、索引的使用
1.當欄位資料更新頻率較低,查詢使用頻率較高並且存在大量重複值是建議使用聚簇索引
2.經常同時存取多列,且每列都含有重複值可考慮建立複合式索引
3.複合索引的前置列一定好控制好,否則無法起到索引的效果。如果查詢時前置列不在查詢條件中則該複合索引不會被使用。前置列一定是使用最頻繁的列
4.多表操作在被實際執行前,查詢最佳化工具會根據串連條件,列出幾組可能的串連方案並從中找出系統開銷最小的最佳方案。串連條件要充份考慮帶有索引的表、行數多的表;內外表的選擇可由公式:外層表中的匹配行數*內層表中每一次尋找的次數確定,乘積最小為最佳方案
5.where子句中對列的任何操作結果都是在sql運行時逐列計算得到的,因此它不得不進行表搜尋,而沒有使用該列上面的索引;如果這些結果在查詢編譯時間就能得到,那麼就可以被sql最佳化器最佳化,使用索引,避免表搜尋(例:select * from record where substring(card_no,1,4)=’5378′ && select * from record where card_no like ‘%78%’)任何對列的操作都將導致表掃描,它包括資料庫函數、計算運算式等等,查詢時要儘可能將操作移至等號右邊
6.where條件中的’in’在邏輯上相當於’or’,所以文法分析器會將in (’0′,’1′)轉化為column=’0′ or column=’1′來執行。我們期望它會根據每個or子句分別尋找,再將結果相加,這樣可以利用column上的索引;但實際上它卻採用了”or策略”,即先取出滿足每個or子句的行,存入臨時資料庫的工作表中,再建立唯一索引以去掉重複行,最後從這個暫存資料表中計算結果。因此,實際過程沒有利用column上索引,並且完成時間還要受tempdb資料庫效能的影響。in、or子句常會使用工作表,使索引失效;如果不產生大量重複值,可以考慮把子句拆開;拆開的子句中應該包含索引
7.要善於使用預存程序,它使sql變得更加靈活和高效
分析mysql索引效率
方法:在一般的SQL語句前加上explain;
分析結果的含義:
1)table:表名;
2)type:串連的類型,(ALL/Range/Ref)。其中ref是最理想的;
3)possible_keys:查詢可以利用的索引名;
4)key:實際使用的索引;
5)key_len:索引中被使用部分的長度(位元組);
6)ref:顯示列名字或者”const”(不明白什麼意思);
7)rows:顯示MySQL認為在找到正確結果之前必須掃描的行數;
8)extra:MySQL的建議;