MySQL Index詳解

FROM:http://blog.csdn.net/tianmo2010/article/details/7930482css

①MySQL Indexhtml

1、SHOW INDEX會返回如下字段mysql

一、Table 表的名稱。sql

二、 Non_unique 若是索引不能包括重複詞,則爲0,若是能夠則爲1。數據庫

三、 Key_name 索引的名稱性能優化

四、 Seq_in_index 索引中的列序列號,從1開始。session

五、 Column_name 列名稱。數據結構

六、 Collation 列以什麼方式存儲在索引中。在MySQL中,有值‘A’(升序)或NULL(無分類)。函數

七、Cardinality 索引中惟一值的數目的估計值。經過運行ANALYZE TABLE或myisamchk -a能夠更新。基數根據被存儲爲整數的統計數據來計數,因此即便對於小型表,該值也沒有必要是精確的。基數越大,當進行聯合時,MySQL使用該索引的機會就越大。性能

八、Sub_part 若是列只是被部分地編入索引,則爲被編入索引的字符的數目。若是整列被編入索引,則爲NULL。

九、 Packed 指示關鍵字如何被壓縮。若是沒有被壓縮,則爲NULL。

十、 Null 若是列含有NULL,則含有YES。若是沒有,則該列含有NO。

十一、 Index_type 用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

十二、 Comment 多種評註,您可使用db_name.tbl_name做爲tbl_name FROM db_name語法的另外一種形式。這兩個語句是等價的:

mysql>SHOW INDEX FROM mytable FROM mydb;

mysql>SHOW INDEX FROM mydb.mytable;

2、使用 CREATE INDEX 建立索引

若是要爲已存在的表建立索引,就須要使用 CREATE INDEX 命令或 ALTER TABLE 來建立索引。

CREATEINDEX idxtitle ON tablename (title)

這條命令將建立與 CREATE TABLE 命令相同的索引。

3、使用 ALTER TABLE 建立索引

ALTER TABLE tablename ADD INDEX idxtitle (title)

4、查看和刪除索引

咱們可使用如下命令來查看已存在的索引:

SHOW INDEX FROM tablename

DROP INDEX indexname ON tablename

DROP INDEX 將刪除 tablename 表上的 indexname 索引,indexname 就是咱們建立表時指定的索引名。

########################################

createtable c(id char(20) not null primary key,`index` char(10));

問題1.若是我忘記把id設爲主鍵如今該怎麼辦?輸入什麼命令?

ALTER TABLE record 

ADD PRIMARY KEY (id); 

例如:ALTER TABLE `abc` ADD PRIMARY KEY(`a`); 

問題2.若是我想把id設爲主鍵,同時想把name改成not null,且改成varchar(10),能不能用一句命令完成問題2?

ALTER TABLE record

ADD PRIMARY KEY (id),

CHANGEname varchar(10) not null;

########################################

索引 mysql index

        索引是一種數據結構,能夠是B-tree, R-tree, 或者 hash 結構。其中R-tree 經常使用於查詢比較接近的數據;B-trees適合用於查找某範圍內的數據,能夠很快的從當前數據找到下條數據;hash結構則適用於隨機訪問的場合,查找每條數據的時間幾乎相同。顯然,若要查找某個時間段的數據,用B-tree結構要比hash結構快好多。  

       優化查詢的有效方法是爲常常查詢的字段創建索引,如無索引查詢數據時,會遍歷整張表(多麼恐怖啊);如有了索引查找會容易不少。當進行 UPDATE, DELETE, 以及 INSERT 操做時,mysql會自動更新索引信息。

 

1.建立和刪除索引( Creating and dropping indexes )

 

建立:

[xhtml]  view plain copy
 
 
  1. mysql> USE sakila;  
  2. Database changed  
  3. mysql> CREATE INDEX idx_actor_first_name ON actor (first_name);  
  4. 或者  
  5. mysql> ALTER TABLE actor ADD INDEX idx_actor_first_name (first_name);  

 

PS:當用 create index 建立索引時,必須指定索引的名字,不然mysql會報錯;
  用 ALTER TABLE 建立索引時,能夠不指定索引名字,若不指定mysql會自動生成索引名字
  
創建索引時,若不想用存儲引擎的默認索引類型,能夠指定索引的類型:

[css]  view plain copy
 
 
  1. mysql> ALTER TABLE temp_index  
  2.  ADD INDEX (first_name),  
  3.  ADD INDEX lname (last_name) USING BTREE  

刪除:

[css]  view plain copy
 
 
  1. DROP INDEX indexname ON tblname  
  2. mysql> DROP INDEX idx_actor_fname ON actor;  
  3. mysql> ALTER TABLE actor DROP INDEX idx_actor_fname;  

 

2.索引類型

BTREE    適合連續讀取數據
RTREE    適合根據一條數據找附近的數據
HASH      適合隨機讀取數據
FULLTEXT    
SPATIAL

 查看某個表中存在的索引類型

[css]  view plain copy
 
 
  1. mysql> SELECT INDEX_NAME,INDEX_TYPE  
  2. -> FROM INFORMATION_SCHEMA.STATISTICS  
  3. -> WHERE TABLE_NAME=’temp_index’;  
  4. +------------+------------+  
  5. | INDEX_NAME | INDEX_TYPE |  
  6. +------------+------------+  
  7. | first_name | HASH       |  
  8. | lname      | BTREE      |  
  9. +------------+------------+  

3.索引冗餘

若是兩個或者多個索引包含了相同的索引信息,那麼就存在索引冗餘。

不一樣類型的索引有不一樣的索引冗餘判斷:
(1) SPATIAL 索引
SPATIAL 只能是一個簡單索引,不能說複合索引;存在冗餘的狀況是同一個字段有兩個索引。
(2) FULLTEXT 索引
若一個FULLTEXT索引是另外一個索引的子集(不考慮字段順序),則存在冗餘。
例如: 表中包含以下兩個索引 
■ (field1)
■ (field1, field2)
(3) HASH 索引
若一個索引在不考慮字段順序的狀況下,索引字段相同,則存在冗餘。
例如:表中包含以下兩個索引 
■ (field1, field2, field3)
■ (field1, field3, field2)
(4) BTREE 索引
若一個索引是另外一個索引的子集(考慮字段順序),則存在冗餘。
例如:表中包含以下兩個索引 
■ (field2)
■ (field2, field1)

PS:若兩個或多個索引有相同的索引字段和字段順序,可是有不一樣的索引類型,這樣的索引是不冗餘的。由於每種索引類型有本身的索引值。

######################################

深刻MySQL數據庫的索引 

摘要:本文介紹索引的類型,已經如何建立索引作了介紹,其中涉及三個比較重要的SQL語句――ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它們的用法。

索引是加速表內容訪問的主要手段,特別對涉及多個表的鏈接的查詢更是如此。這是數據庫優化中的一個重要內容,咱們要了解爲何須要索引,索引如何工做以及怎樣利用它們來優化查詢。本節中,咱們將介紹索引的特色,以及建立和刪除索引的語法。 

索引的特色

全部的MySQL列類型能被索引。在相關的列上的使用索引是改進SELECT操做性能的最好方法。

一個表最多可有16個索引。最大索引長度是256個字節,儘管這能夠在編譯MySQL時被改變。

對於CHAR和 VARCHAR列,你能夠索引列的前綴。這更快而且比索引整個列須要較少的磁盤空間。對於BLOB和TEXT列,你必須索引列的前綴,你不能索引列的所有。

MySQL能在多個列上建立索引。一個索引能夠由最多15個列組成。(在CHAR和VARCHAR列上,你也可使用列的前綴做爲一個索引的部分)。

雖然隨着 MySQL 的進一步開發建立索引的約束將會愈來愈少,但如今仍是存在一些約束的。下面的表根據索引的特性,給出了 ISAM 表和 MyISAM 表之間的差異:

表2-1 通道信息特徵字對照表索引的特色 ISAM 表 MyISAM 表

NULL 值

BLOB 和 TEXT 列

每一個表中的索引數

每一個索引中的列數

最大索引行尺寸

不容許

不能索引

16

16

256 字節 容許

只能索引列的前綴

32

16

500 字節

今後表中能夠看到,對於 ISAM 表來講,其索引列必須定義爲 NOT NULL,而且不能對 BLOB 和 TEXT 列進行索引。MyISAM 表類型去掉了這些限制,並且減緩了其餘的一些限制。兩種表類型的索引特性的差別代表,根據所使用的 MySQL 版本的不一樣,有可能對某些列不能進行索引。例如,若是使用3.23 版之前的版本,則不能對包含 NULL 值的列進行索引。

索引有以下的幾種狀況:

INDEX索引:一般意義的索引,某些狀況下KEY是它的一個同義詞。索引的列能夠包括重複的值。

UNIQUE索引:惟一索引,保證了列不包含重複的值,對於多列惟一索引,它保證值的組合不重複。

PRIMARY KEY索引:也UNIQUE索引很是相似。事實上,PRIMARYKEY索引僅是一個具備PRIMARY名稱的UNIQUE索引。這表示一個表只能包含一個PRIMARY KEY。 

用Alter Table語句建立與刪除索引

爲了給現有的表增長一個索引,可以使用 ALTER TABLE 或CREATE INDEX 語句。ALTER TABLE 最經常使用,由於可用它來建立普通索引、UNIQUE 索引或 PRIMARY KEY 索引,如:

ALTER TABLE tbl_name ADD INDEX index_name  (column_list)

ALTER TABLE tbl_name ADD UNIQUE index_name  (column_list)

ALTER TABLE tbl_name ADD PRIMARY KEY index_name  (column_list)

其中 tbl_name 是要增長索引的表名,而 column_list 指出對哪些列進行索引。一個(col1,col2,...)形式的列表創造一個多列索引。索引值有給定列的值串聯而成。若是索引由不止一列組成,各列名之間用逗號分隔。索引名 index_name 是可選的,所以能夠不寫它,MySQL 將根據第一個索引列賦給它一個名稱。ALTER TABLE 容許在單個語句中指定多個表的更改,所以能夠在同時建立多個索引。

一樣,也能夠用ALTER TABLE語句刪除列的索引:

ALTER TABLE tbl_name DROP INDEX index_name

ALTER TABLE tbl_name DROP PRIMARY KEY

注意上面第一條語句能夠用來刪除各類類型的索引,而第三條語句只在刪除 PRIMARY KEY 索引時使用;在此情形中,不須要索引名,由於一個表只可能具備一個這樣的索引。若是沒有明確地建立做爲 PRIMARY KEY 的索引,但該表具備一個或多個 UNIQUE 索引,則 MySQL 將刪除這些 UNIQUE 索引中的第一個。

若是從表中刪除了列,則索引可能會受到影響。若是所刪除的列爲索引的組成部分,則該列也會從索引中刪除。若是組成索引的全部列都被刪除,則整個索引將被刪除。

例如,對於上面所使用的student爲例,你可能想爲之建立這樣的索引,以加速表的檢索速度:

mysql> ALTER TABLE student

-> ADD PRIMARY KEY(id),

-> ADD INDEXmark(english,Chinese,history);

這個例子,既包括PRIMARY索引,也包括多列索引。記住,使用 PRIMARY索引的列,必須是一個具備NOT NULL屬性的列,若是你願意查看建立的索引的狀況,可使用SHOW INDEX語句:

mysql> SHOW INDEX FROM student;

其結果爲:

+---------+------------+----------+--------------+-------------+-

| Table  | Non_unique | Key_name | Seq_in_index | Column_name |

+---------+------------+----------+--------------+-------------+-

| student |          0 | PRIMARY  |           1 | id          |

| student |          1 | mark     |            1 | english     |

| student |          1 | mark     |            2 | chinese     |

| student |          1 | mark     |            3 | history     |

+---------+------------+----------+--------------+-------------+-

因爲列數太多,上表並無包括全部的輸出,讀者能夠試着本身查看。

再使用ALTER TABLE語句刪除索引,刪除索引須要知道索引的名字,你能夠經過SHOW INDEX語句獲得:

mysql> ALTER TABLE student DROP PRIMARYKEY,

   -> DROP INDEX mark;

再產看錶中的索引,其語句和輸出爲:

mysql> SHOW INDEX FROM student;

Empty set (0.01 sec) 

用CREATE\DROP INDEX建立索引

還能夠用CREATE INDEX語句來建立索引.CREATE INDEX 是在 MySQL 3.23版中引入的,但若是使用3.23 版之前的版本,可利用 ALTER TABLE 語句建立索引(MySQL 一般在內部將 CREATE INDEX 映射到 ALTER TABLE)。該語句建立索引的語法以下:

CREATE UNIQUE INDEX index_name ON tbl_name(column_list)

CREATE INDEX index_name ON tbl_name(column_list) tbl_name、index_name 和 column_list 具備與 ALTER TABLE 語句中相同的含義。這裏索引名不可選。很明顯,CREATE INDEX 可對錶增長普通索引或 UNIQUE 索引,不能用 CREATE INDEX 語句建立 PRIMARY KEY 索引。

可利用 DROP INDEX語句來刪除索引。相似於 CREATE INDEX 語句,DROP INDEX 一般在內部做爲一條 ALTER TABLE 語句處理,而且DROP INDEX是在 MySQL 3.22 中引入的。

刪除索引語句的語法以下:

DROP INDEX index_name ON tbl_name

仍是上一節的例子,因爲CREATE INDEX不能建立PRIMARY索引,因此這裏咱們只建立一個多列索引:

mysql> CREATE INDEX mark ONstudent(english,chinese,history);

一樣的檢查student表,可知:

mysql> SHOW INDEX FROM student;

+---------+------------+----------+--------------+-------------+

| Table  | Non_unique | Key_name | Seq_in_index | Column_name |

+---------+------------+----------+--------------+-------------+

| student |          1 | mark     |           1 | english     |

| student |          1 | mark     |            2 | chinese     |

| student |          1 | mark     |            3 | history     |

+---------+------------+----------+--------------+-------------+

而後使用下面的語句刪除索引:

mysql> DROP INDEX mark ON student;

在建立表時指定索引

要想在發佈 CREATE TABLE 語句時爲新表建立索引,所使用的語法相似於 ALTER TABLE 語句的語法,可是應該在您定義表列的語句部分指定索引建立子句,以下所示:

[sql]  view plain copy
 
  1. CREATE TABLE tbl_name  
  2. (  
  3. …  
  4. INDEX index_name (column_list),  
  5. KEY index_name (column_list),  
  6. UNIQUE index_name (column_list),  
  7. PRIMARY KEY index_name (column_list),  
  8. …  
  9. )  

與ALTER TABLE 同樣,索引名對於 INDEX 和 UNIQUE 都是可選的,若是未給出,MySQL 將爲其選一個。另外,這裏KEY時INDEX的一個別名,具備相同的意義。

有一種特殊情形:可在列定義以後增長 PRIMARY KEY 建立一個單列的PRIMARY KEY 索引,以下所示:

[sql]  view plain copy
 
  1. CREATE TABLE tbl_name  
  2. (  
  3.   iINT NOT NULL PRIMARY KEY  
  4. )  

該語句等價於如下的語句:

[sql]  view plain copy
 
  1. CREATE TABLE tbl_name  
  2. (  
  3.   iINT NOT NULL,  
  4.  PRIMARY KEY (i)  
  5. )  

前面全部表建立樣例都對索引列指定了 NOT NULL。若是是 ISAM 表,這是必須的,由於不能對可能包含 NULL 值的列進行索引。若是是 MyISAM 表,索引列能夠爲 NULL,只要該索引不是 PRIMARY KEY 索引便可。

在CREATE TBALE語句中能夠某個串列的前綴進行索引(列值的最左邊 n 個字符)。

若是對某個串列的前綴進行索引,應用 column_list 說明符表示該列的語法爲 col_name(n) 而不用col_name。例如,下面第一條語句建立了一個具備兩個 CHAR 列的表和一個由這兩列組成的索引。第二條語句相似,但只對每一個列的前綴進行索引:

[sql]  view plain copy
 
  1. CREATE TABLE tbl_name  
  2. (  
  3. name CHAR(30),  
  4. address CHAR(60),  
  5. INDEX (name,address)  
  6. )  
[sql]  view plain copy
 
  1. CREATE TABLE tbl_name  
  2. (  
  3. name CHAR(30),  
  4. address CHAR(60),  
  5. INDEX (name(10),address(20))  
  6. )  

你能夠檢查所建立表的索引:

mysql> SHOW INDEX FROM tbl_name;

+----------+------------+----------+--------------+-------------+-

| Table   | Non_unique | Key_name | Seq_in_index | Column_name |

+----------+------------+----------+--------------+-------------+-

| tbl_name |          1 | name     |            1 | name        |

| tbl_name |          1 | name     |            2 | address     |

+----------+------------+----------+--------------+-------------+-

在某些狀況下,可能會發現必須對列的前綴進行索引。例如,索引行的長度有一個最大上限,所以,若是索引列的長度超過了這個上限,那麼就可能須要利用前綴進行索引。在 MyISAM 表索引中,對 BLOB 或 TEXT 列也須要前綴索引。

對一個列的前綴進行索引限制了之後對該列的更改;不能在不刪除該索引並使用較短前綴的狀況下,將該列縮短爲一個長度小於索引所用前綴的長度的列。 

總結

本節對索引的類型,已經如何建立索引作了介紹,其中涉及三個比較重要的SQL語句――ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它們的用法。

索引最重要的功能是,經過使用索引加速表的檢索,有關這方面的知識,將在第十章數據庫優化中介紹。 

思考題

一、創建一個以下所述的表:

data:FLOAT列,使用隨機函數填充數據

birth:DATETIME列,填充當前時間。

而後,請錄入幾條數據。最後計算data列的平均值、總和、極值,而且按照data列降序排序檢索值。

二、分別使用標準SQL模式和擴展正規表達式模式匹配,匹配上面建立的表,假設你建立表的當前日期爲2001-01-01,用模式匹配檢索出birth列包含該日期的值。(實際上,上面的表中記錄都是同一日期錄入的,所以實際將返回所有記錄。)

三、爲前幾章使用的數據表建立索引:

student:爲id段建立一個PRIMARY索引,爲english、chinese和history建立一個多列索引。

pet:爲name和owner段建立一個多類索引。

四、刪除爲pet表建立的索引。

##################################################

MySQL Index的使用

如下是理論知識備忘:

1、什麼是索引?
  索引用來快速地尋找那些具備特定值的記錄,全部MySQL索引都以B-樹的形式保存。若是沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表的全部記錄,直至找到符合要求的記錄。表裏面的記錄數量越多,這個操做的代價就越高。若是做爲搜索條件的列上已經建立了索引,MySQL無需掃描任何記錄便可迅速獲得目標記錄所在的位置。若是表有1000個記錄,經過索引查找記錄至少要比順序掃描記錄快100倍。
  
  假設咱們建立了一個名爲people的表:
  
  CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );
  
  而後,咱們徹底隨機把1000個不一樣name值插入到people表。下圖顯示了people表所在數據文件的一小部分:
  
  能夠看到,在數據文件中name列沒有任何明確的次序。若是咱們建立了name列的索引,MySQL將在索引中排序name列:
  
  對於索引中的每一項,MySQL在內部爲它保存一個數據文件中實際記錄所在位置的「指針」。所以,若是咱們要查找name等於「Mike」記錄的 peopleid(SQL命令爲「SELECT peopleid FROM people WHERE name='Mike';」),MySQL可以在name的索引中查找「Mike」值,而後直接轉到數據文件中相應的行,準確地返回該行的 peopleid(999)。在這個過程當中,MySQL只需處理一個行就能夠返回結果。若是沒有「name」列的索引,MySQL要掃描數據文件中的全部記錄,即1000個記錄!顯然,須要MySQL處理的記錄數量越少,則它完成任務的速度就越快。
  
  2、索引的類型
  MySQL提供多種索引類型供選擇:
  
  普通索引
  這是最基本的索引類型,並且它沒有惟一性之類的限制。普通索引能夠經過如下幾種方式建立:
  建立索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
  修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
  建立表的時候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );
  
  惟一性索引
  這種索引和前面的「普通索引」基本相同,但有一個區別:索引列的全部值都只能出現一次,即必須惟一。惟一性索引能夠用如下幾種方式建立:
  建立索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
  修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
  建立表的時候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );
  
  主鍵
  主鍵是一種惟一性索引,但它必須指定爲「PRIMARY KEY」。若是你曾經用過AUTO_INCREMENT類型的列,你可能已經熟悉主鍵之類的概念了。主鍵通常在建立表的時候指定,例如「CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); 」。可是,咱們也能夠經過修改表的方式加入主鍵,例如「ALTER TABLE tablename ADD PRIMARY KEY (列的列表); 」。每一個表只能有一個主鍵。
  
  全文索引
  MySQL從3.23.23版開始支持全文索引和全文檢索。在MySQL中,全文索引的索引類型爲FULLTEXT。全文索引能夠在VARCHAR或者TEXT類型的列上建立。它能夠經過CREATE TABLE命令建立,也能夠經過ALTER TABLE或CREATE INDEX命令建立。對於大規模的數據集,經過ALTER TABLE(或者CREATE INDEX)命令建立全文索引要比把記錄插入帶有全文索引的空表更快。本文下面的討論再也不涉及全文索引,要了解更多信息,請參見MySQL documentation。
  
  3、單列索引與多列索引
  索引能夠是單列索引,也能夠是多列索引。下面咱們經過具體的例子來講明這兩種索引的區別。假設有這樣一個people表:
  
  CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname CHAR(50) NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT NOT NULL, PRIMARY KEY (peopleid) );
  
  下面是咱們插入到這個people表的數據:
  
  這個數據片斷中有四個名字爲「Mikes」的人(其中兩個姓Sullivans,兩個姓McConnells),有兩個年齡爲17歲的人,還有一個名字不同凡響的Joe Smith。
  
  這個表的主要用途是根據指定的用戶姓、名以及年齡返回相應的peopleid。例如,咱們可能須要查找姓名爲Mike Sullivan、年齡17歲用戶的peopleid(SQL命令爲SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age=17;)。因爲咱們不想讓MySQL每次執行查詢就去掃描整個表,這裏須要考慮運用索引。
  
  首先,咱們能夠考慮在單個列上建立索引,好比firstname、lastname或者age列。若是咱們建立firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL將經過這個索引迅速把搜索範圍限制到那些firstname='Mike'的記錄,而後再在這個「中間結果集」上進行其餘條件的搜索:它首先排除那些lastname不等於「Sullivan」的記錄,而後排除那些age不等於17的記錄。當記錄知足全部搜索條件以後,MySQL就返回最終的搜索結果。
  
  因爲創建了firstname列的索引,與執行表的徹底掃描相比,MySQL的效率提升了不少,但咱們要求MySQL掃描的記錄數量仍舊遠遠超過了實際所須要的。雖然咱們能夠刪除firstname列上的索引,再建立lastname或者 age列的索引,但總地看來,不論在哪一個列上建立索引搜索效率仍舊類似。
  
  爲了提升搜索效率,咱們須要考慮運用多列索引。若是爲firstname、lastname和age這三個列建立一個多列索引,MySQL只需一次檢索就可以找出正確的結果!下面是建立這個多列索引的SQL命令:
  
  ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);
  
  因爲索引文件以B-樹格式保存,MySQL可以當即轉到合適的firstname,而後再轉到合適的lastname,最後轉到合適的age。在沒有掃描數據文件任何一個記錄的狀況下,MySQL就正確地找出了搜索的目標記錄!
  
  那麼,若是在firstname、lastname、age這三個列上分別建立單列索引,效果是否和建立一個firstname、lastname、 age的多列索引同樣呢?答案是否認的,二者徹底不一樣。當咱們執行查詢的時候,MySQL只能使用一個索引。若是你有三個單列的索引,MySQL會試圖選擇一個限制最嚴格的索引。可是,即便是限制最嚴格的單列索引,它的限制能力也確定遠遠低於firstname、lastname、age這三個列上的多列索引。
  
  4、最左前綴
  多列索引還有另一個優勢,它經過稱爲最左前綴(Leftmost Prefixing)的概念體現出來。繼續考慮前面的例子,如今咱們有一個firstname、lastname、age列上的多列索引,咱們稱這個索引爲fname_lname_age。當搜索條件是如下各類列的組合時,MySQL將使用fname_lname_age索引:
  
  firstname,lastname,age
  firstname,lastname
  firstname
  從另外一方面理解,它至關於咱們建立了(firstname,lastname,age)、(firstname,lastname)以及(firstname)這些列組合上的索引。下面這些查詢都可以使用這個fname_lname_age索引:
  
  SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan'; SELECT peopleid FROM people WHERE firstname='Mike'; The following queries cannot use the index at all: SELECT peopleid FROM people WHERE lastname='Sullivan'; SELECT peopleid FROM people WHERE age='17'; SELECT peopleid FROM people WHERE lastname='Sullivan' AND age='17';
  
  5、選擇索引列
  在性能優化過程當中,選擇在哪些列上建立索引是最重要的步驟之一。能夠考慮使用索引的主要有兩種類型的列:在WHERE子句中出現的列,在join子句中出現的列。請看下面這個查詢:
  
  SELECT age ## 不使用索引
  FROM people WHERE firstname='Mike' ## 考慮使用索引
  AND lastname='Sullivan' ## 考慮使用索引
  
  這個查詢與前面的查詢略有不一樣,但仍屬於簡單查詢。因爲age是在SELECT部分被引用,MySQL不會用它來限制列選擇操做。所以,對於這個查詢來講,建立age列的索引沒有什麼必要。下面是一個更復雜的例子:
  
  SELECT people.age, ##不使用索引
  town.name ##不使用索引
  FROM people LEFT JOIN town ON
  people.townid=town.townid ##考慮使用索引
  WHERE firstname='Mike' ##考慮使用索引
  AND lastname='Sullivan' ##考慮使用索引
  
  與前面的例子同樣,因爲firstname和lastname出如今WHERE子句中,所以這兩個列仍舊有建立索引的必要。除此以外,因爲town表的townid列出如今join子句中,所以咱們須要考慮建立該列的索引。
  
  那麼,咱們是否能夠簡單地認爲應該索引WHERE子句和join子句中出現的每個列呢?差很少如此,但並不徹底。咱們還必須考慮到對列進行比較的操做符類型。MySQL只有對如下操做符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE。能夠在LIKE操做中使用索引的情形是指另外一個操做數不是以通配符(%或者_)開頭的情形。例如,「SELECT peopleid FROM peopleWHERE firstname LIKE 'Mich%';」這個查詢將使用索引,但「SELECT peopleid FROM people WHERE firstname LIKE '%ike';」這個查詢不會使用索引。
  
  6、分析索引效率

  如今咱們已經知道了一些如何選擇索引列的知識,但還沒法判斷哪個最有效。MySQL提供了一個內建的SQL命令幫助

 

1、 MySQL建表,字段需設置爲非空,需設置字段默認值。

2、 MySQL建表,字段需NULL時,需設置字段默認值,默認值不爲NULL。

3、 MySQL建表,若是字段等價於外鍵,應在該字段加索引。

4、 MySQL建表,不一樣表之間的相同屬性值的字段,列類型,類型長度,是否非空,是否默認值,需保持一致,不然沒法正確使用索引進行關聯對比。

5、 MySQL使用時,一條SQL語句只能使用一個表的一個索引。全部的字段類型均可以索引,多列索引的屬性最多15個。

6、 若是能夠在多個索引中進行選擇,MySQL一般使用找到最少行的索引,索引惟一值最高的索引。

7、 創建索引index(part1,part2,part3),至關於創建了 index(part1),index(part1,part2)和index(part1,part2,part3)三個索引。

8、 MySQL針對like語法必須以下格式才使用索引:

SELECT * FROM t1 WHERE key_col LIKE 'ab%' ;

9、 SELECT COUNT(*) 語法在沒有where條件的語句中執行效率沒有SELECT COUNT(col_name)快,可是在有where條件的語句中執行效率要快。

10、 在where條件中多個and的條件中,必須都是一個多列索引的key_part屬性並且必須包含key_part1。各自單一索引的話,只使用遍歷最少行的那個索引。

11、 在where條件中多個or的條件中,每個條件,都必須是一個有效索引。

12、 ORDER BY 後面的條件必須是同一索引的屬性,排序順序必須一致(好比都是升序或都是降序)。

十3、 全部GROUP BY列引用同一索引的屬性,而且索引必須是按順序保存其關鍵字的。

十4、 JOIN 索引,全部匹配ON和where的字段應創建合適的索引。

十5、 對智能的掃描全表使用FORCE INDEX告知MySQL,使用索引效率更高。

十6、 按期ANALYZE TABLE tbl_name爲掃描的表更新關鍵字分佈 。

十7、 按期使用慢日誌檢查語句,執行explain,分析可能改進的索引。

十8、 條件容許的話,設置較大的key_buffer_size和query_cache_size的值(全局參數),和sort_buffer_size的值(session變量,建議不要超過4M)。

相關文章
相關標籤/搜索