標籤:
轉自 :http://blog.csdn.net/wud_jiyanhui/article/details/7403375
什麼是索引
索引時一種特殊的檔案,他們包涵著對資料表裡所有記錄的引用指標。當對資料表記錄進行更新後,都會對索引進行重新整理。索引會佔用相當大的空間,應該只為經常查詢和最經常排序的資料列建立索引。
索引類型
①普通索引:這是最基本的索引類型,而且它沒有唯一性之類的限制。普通索引可以通過以下幾種方式建立:
I.建立索引 例如:CREATE INDEX <索引的名字> ON tablename (列的列表);
II.修改表 例如:ALTER TABLE tablename ADDINDEX [索引的名字] (列的列表);
III.建立表的時候指定索引 例如:CREATE TABLE tablename ( [...],INDEX [索引的名字] (列的列表) );
②唯一性索引
這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。
建立方式:和普通索引建立方式一樣,將“INDEX”替換成“UNIQUE”就可以了
③主鍵索引
主鍵是一種唯一性索引,但它必須指定為“PRIMARY KEY”。每個表只能有一個主鍵
④全文索引
文字欄位上的普通索引只能加快對出現在欄位內容最前面的字串進行的檢索操作。如果欄位裡存放的是由學多個單詞構成的大段文字,普通索引就沒什麼作用“%word%”費時,效率低,回應時間長。
產生全文索引時,mysql將把文中出現的所有單詞建立一份清單,查詢操作根據這份清單去檢索相關資料記錄。
但目前全文索引對中文支援很差,需要相關分詞外掛程式。(如:http://code.google.com/p/mysqlcft/)
多重索引
索引可以是單列索引,也可以是多列索引。 建立多列索引:ALTERTABLE people ADD INDEX fname_lname_age (firstname,lastname,age);
由於索引檔案以B-樹格式儲存,MySQL能夠立即轉到合適的firstname,然後再轉到合適的lastname,最後轉到合適的age。MySQL只需一次檢索就能夠找出正確的結果!在沒有掃描資料檔案任何一個記錄的情況下,MySQL就正確地找出了搜尋的目標記錄!
多重索引還有另外一個優點,它通過稱為最左首碼(Leftmost Prefixing)的概念體現出來。 假若現在我們有一個firstname、lastname、age列上的多重索引,我們稱這個索引為fname_lname_age。當搜尋條件是以下各種列的組合時,MySQL將使用fname_lname_age索引: firstname,lastname,age firstname,lastname firstname
選擇索引列
在效能最佳化過程中,選擇在哪些列上建立索引是最重要的步驟之一。可以考慮使用索引的主要有兩種類型的列: 在WHERE子句中出現的列 在join子句中出現的列
例子:
SELECT people.age, ##不使用索引
town.name ##不使用索引
FROM people LEFT JOIN town ON
people.townid=town.townid ##考慮使用索引
WHERE firstname=‘Mike‘##考慮使用索引
AND lastname=‘Sullivan‘##考慮使用索引
那麼,我們是否可以簡單地認為應該索引WHERE子句和join子句中出現的每一個列呢?
差不多如此,但並不完全。我們還必須考慮到對列進行比較的操作符類型。MySQL只有對以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE。可以在LIKE操作中使用索引的情形是指另一個運算元不是以萬用字元(%或者_)開頭的情形。
分析索引效率
EXPLAIN<SQL命令 例子: EXPLAIN SELECT peopleid FROMpeople WHERE firstname=‘Mike‘AND lastname=‘Sullivan‘ AND age=‘17‘; 這個命令將返回下面這種分析結果: ------------------------ Table type possible_keys key key_len ref rows Extra people ref fname_lname_age fname_lname_age 102 const,const,const 1 Where used ------------------------ table:這是表的名字。 type:串連操作的類型。下面是MySQL文檔關於ref連線類型的說明: 對於每一種與另一個表中記錄的組合,MySQL將從當前的表讀取所有帶有匹配索引值的記錄。如果串連操作只使用鍵的最左首碼,或者如果鍵不是UNIQUE或PRIMARY KEY類型(換句話說,如果串連操作不能根據索引值選擇出唯一行),則MySQL使用ref連線類型。如果串連操作所用的鍵只匹配少量的記錄,則ref是一種好的連線類型。” 在本例中,由於索引不是UNIQUE類型,ref是我們能夠得到的最好連線類型。 如果EXPLAIN顯示連線類型是“ALL”,而且你並不想從表裡面選擇出大多數記錄,那麼MySQL的操作效率將非常低,因為它要掃描整個表。你可以加入更多的索引來解決這個問題。預知更多資訊,請參見MySQL的手冊說明。 possible_keys:可能可以利用的索引的名字。這裡的索引名字是建立索引時指定的索引暱稱;如果索引沒有暱稱,則預設顯示的是索引中第一個列的名字(在本例中,它是“firstname”)。預設索引名字的含義往往不是很明顯。 Key: 它顯示了MySQL實際使用的索引的名字。如果它為空白(或NULL),則MySQL不使用索引。 key_len: 索引中被使用部分的長度,以位元組計。在本例中,key_len是102,其中firstname佔50位元組,lastname佔50位元組,age佔2位元組。如果MySQL只使用索引中的firstname部分,則key_len將是50。 ref: 它顯示的是列的名字(或單詞“const”),MySQL將根據這些列來選擇行。在本例中,MySQL根據三個常量選擇行。 rows: MySQL所認為的它在找到正確的結果之前必須掃描的記錄數。顯然,這裡最理想的數字就是1。 Extra: 這裡可能出現許多不同的選項,其中大多數將對查詢產生負面影響。在本例中,MySQL只是提醒我們它將用WHERE子句限制搜尋結果集。
索引設計 一般針對資料分散的關鍵字進行建立索引,比如ID、login_id,user_id,等建立索引沒有意義 盡量使用短索引,一般對int、char/varchar、date/time 等類型的欄位建立索引 需要的時候建立聯合索引,但是要注意查詢SQL語句的編寫謹慎建立 unique 類型的索引(唯一索引) 一般建議每條記錄最好有一個能快速定位的獨一無二定位的唯一標示(索引) 不要過度索引,單表建立的索引不要超過5個,否則更新索引將很耗時 能夠快速縮小結果集的 WHERE 條件寫在前面,如果有恒量條件,也盡量放在前面 盡量避免使用 GROUP BY、DISTINCT、OR、IN等語句的使用,避免使用聯表查詢和子查詢,因為將使執行效率大大下降能夠使用索引的欄位盡量進行有效合理排列,如果使用了聯合索引,請注意提取欄位的前後順序 如果where子句的查詢條件裡有不等號(wherecolumns !=…),mysql將無法使用索引 類似地,在SQL裡使用了MySQL部分內建函數,索引將失效,同時將無法使用 MySQL的 QueryCache,比如 LEFT(),SUBSTR(), TO_DAYS()DATE_FORMAT(), 等,如果使用了 OR 或 IN,索引也將失效 在join操作中,mysql只有在主鍵和外鍵的資料類型相同時才能使用索引 針對索引欄位使用 >, >=, =, <, <=, IF NULL和BETWEEN 將會使用索引, 如果對某個索引欄位進行 LIKE 查詢和REGEXP,mysql只有在搜尋模板的第一個字元不是萬用字元的情況下才能使用索引。比如說,使用 LIKE ‘%abc%’不能使用索引,使用 LIKE ‘abc%’ 將能夠使用索引 在orderby操作中,mysql只有在排序條件不是一個查詢條件運算式的情況下才使用索引
Mysql 索引 轉載