MySQL創建索引


索引是創建在表上的,對數據庫表中一列或多列的值進行排序的一種結構

其作用主要在於提高查詢的速度,降低數據庫系統的性能開銷

通過索引,查詢數據不必讀完記錄的全部信息進行匹配,而是只查詢索引列

索引相當於字典中的音序表,要查詢某字時可以在音序表中找到

然后直接跳轉到那一音序所在位置,而不必從字典第一頁開始翻,逐字匹配

tips:索引雖能提高查詢速度,但在插入記錄時會按照索引進行排序,因此降低了插入速度

     最好的操作方式是先刪除索引,插入大量記錄后再創建索引


索引分類

1.普通索引:不附加任何限制條件,可創建在任何數據類型中

2.唯一性索引:使用unique參數可以設置索引為唯一性索引,在創建索引時,限制該索引的值必須唯一,主鍵就是一種唯一性索引

3.全文索引:使用fulltext參數可以設置索引為全文索引。全文索引只能創建在char、varchar或text類型的字段上。查詢數據量較大的字符串類型字段時,效果明顯。但只有MyISAM存儲引擎支持全文檢索

4.單列索引:在表中單個字段上創建的索引,單列索引可以是任何類型,只要保證索引只對應一個一個字段

5.多列索引:在表中多個字段上創建的索引,該索引指向創建時對應的多個字段

6.空間索引:使用spatial參數可以設置索引為空間索引,空間索引只能建立在空間數據類型上比如geometry,並且不能為空,目前只有MyISAM存儲引擎支持

 

在創建表時創建索引
創建普通索引

mysql> create table index1(
    -> id int,
    -> name varchar(20),
    -> sex boolean,
    -> index(id)
    -> );
Query OK, 0 rows affected (0.11 sec)

此處在id字段上創建索引,show create table可查看

創建唯一性索引

mysql> create table index2(
    -> id int unique,
    -> name varchar(20),
    -> unique index index2_id(id ASC)
    -> );
Query OK, 0 rows affected (0.12 sec)

此處使用id字段創建了一個名為index2_id的索引

這里的id字段可以不設置唯一性約束,但這樣一來索引就沒有作用

創建全文索引

mysql> create table index3(
    -> id int,
    -> info varchar(20),
    -> fulltext index index3_info(info)
    -> )engine=MyISAM;
Query OK, 0 rows affected (0.07 sec)

要注意創建全文索引時只能使用MyISAM存儲引擎

 


創建單列索引

mysql> create table index4(
    -> id int,
    -> subject varchar(30),
    -> index index4_st(subject(10))
    -> );
Query OK, 0 rows affected (0.12 sec)

此處subject字段長度是30,而索引長度則是10

這么做的目的在於提高查詢速度,對於字符型的數據不用查詢全部信息


創建多列索引

mysql> create table index5(
    -> id int,
    -> name varchar(20),
    -> sex char(4),
    -> index index5_ns(name,sex)
    -> );
Query OK, 0 rows affected (0.10 sec)

可以看出,這里使用了name字段和sex字段創建索引列

創建空間索引

mysql> create table index6(
    -> id int,
    -> space geometry not null,
    -> spatial index index6_sp(space)
    -> )engine=MyISAM;
Query OK, 0 rows affected (0.07 sec)

這里需要注意空間space字段不能為空,還有存儲引擎

在已經存在的表上創建索引
創建普通索引

mysql> create index index7_id on example0(id);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

這里在現有表的id字段上創建了一條名為index7_id的索引

創建唯一性索引

mysql> create unique index index8_id on example1(course_id);
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

此處只需要在index關鍵字前面加上unique即可

至於表中的course_id字段,最要也設置唯一性約束條件

創建全文索引

mysql> create fulltext index index9_info on example2(info);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

fulltext關鍵字用來設置全文引擎,此處的表必須是MyISAM存儲引擎

創建單列索引

mysql> create index index10_addr on example3(address(4));
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

此表中address字段的長度是20,這里只查詢4字節,不需要全部查詢

創建多列索引

mysql> create index index11_na on example4(name,address);
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

索引創建好之后,查詢中必須有name字段才能使用

創建空間索引

mysql> create spatial index index12_line on example5(space);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

這里需要注意存儲引擎是MyISAM,還有空間數據類型

用alter table語句來創建索引
創建普通索引

mysql> alter table example6 add index index13_n(name(20));
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

創建唯一性索引

mysql> alter table example7 add unique index index14_id(id);
Query OK, 0 rows affected (0.20 sec)
Records: 0  Duplicates: 0  Warnings: 

創建全文索引

mysql> alter table example8 add fulltext index index15_info(info);
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

創建單列索引

mysql> alter table example9 add index index16_addr(address(4));
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

創建多列索引

mysql> alter table example10 add index index17_in(id,name);
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

創建空間索引

mysql> alter table example11 add spatial index index18_space(space);
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

到此,三種操作方式,每種索引類別的建立就都列舉了

對於索引,重要的是理解索引的概念,明白索引的種類

更多的是自己的使用經驗

最后來看看索引的刪除

刪除索引

mysql> drop index index18_space on example11;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

這里是剛剛創建的一條索引

其中index18_space是索引名,example11是表名

 

mysql索引最左匹配原則的理解

 

這是你的表結構,有三個字段,分別是id,name,cid
CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `cid` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name_cid_INX` (`name`,`cid`),) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
索引方面:id是主鍵,(name,cid)是一個多列索引。
-----------------------------------------------------------------------------
下面是你有疑問的兩個查詢:
 
EXPLAIN SELECT * FROM student WHERE cid=1;
 
EXPLAIN SELECT * FROM student WHERE cid=1 AND name='小紅';
 
 
你的疑問是:sql查詢用到索引的條件是必須要遵守最左前綴原則,為什么上面兩個查詢還能用到索引?
---------------------------------------------------------------------------------------------------------------------------
 
講上面問題之前,我先補充一些知識,因為我覺得你對索引理解是狹隘的:
上述你的兩個查詢的explain結果中顯示用到索引的情況類型是不一樣的。,可觀察explain結果中的type字段。你的查詢中分別是:
1. type: index
2. type: ref
 
解釋:
index:這種類型表示是mysql會對整個該索引進行掃描。要想用到這種類型的索引,對這個索引並無特別要求,只要是索引,或者某個復合索引的一部分,mysql都可能會采用index類型的方式掃描。但是呢,缺點是效率不高,mysql會從索引中的第一個數據一個個的查找到最后一個數據,直到找到符合判斷條件的某個索引。
 
所以:對於你的第一條語句:
EXPLAIN SELECT * FROM student WHERE cid=1;
判斷條件是cid=1,而cid是(name,cid)復合索引的一部分,沒有問題,可以進行index類型的索引掃描方式。explain顯示結果使用到了索引,是index類型的方式。
 
---------------------------------------------------------------------------------------------------------------------------
 
ref:這種類型表示mysql會根據特定的算法快速查找到某個符合條件的索引,而不是會對索引中每一個數據都進行一 一的掃描判斷,也就是所謂你平常理解的使用索引查詢會更快的取出數據。而要想實現這種查找,索引卻是有要求的,要實現這種能快速查找的算法,索引就要滿足特定的數據結構。簡單說,也就是索引字段的數據必須是有序的,才能實現這種類型的查找,才能利用到索引。
 
 
有些了解的人可能會問,索引不都是一個有序排列的數據結構么。不過答案說的還不夠完善,那只是針對單個索引,而復合索引的情況有些同學可能就不太了解了。
 
下面就說下復合索引:
以該表的(name,cid)復合索引為例,它內部結構簡單說就是下面這樣排列的:
mysql創建復合索引的規則是首先會對復合索引的最左邊的,也就是第一個name字段的數據進行排序,在第一個字段的排序基礎上,然后再對后面第二個的cid字段進行排序。其實就相當於實現了類似 order by name cid這樣一種排序規則。
 
所以:第一個name字段是絕對有序的,而第二字段就是無序的了。所以通常情況下,直接使用第二個cid字段進行條件判斷是用不到索引的,當然,可能會出現上面的使用index類型的索引。這就是所謂的mysql為什么要強調最左前綴原則的原因。
 
那么什么時候才能用到呢?
當然是cid字段的索引數據也是有序的情況下才能使用咯,什么時候才是有序的呢?觀察可知,當然是在name字段是等值匹配的情況下,cid才是有序的。發現沒有,觀察兩個name名字為 c 的cid字段是不是有序的呢。從上往下分別是4 5。
這也就是mysql索引規則中要求復合索引要想使用第二個索引,必須先使用第一個索引的原因。(而且第一個索引必須是等值匹配)。
---------------------------------------------------------------------------------------------------------------------------
所以對於你的這條sql查詢:
EXPLAIN SELECT * FROM student WHERE cid=1 AND name='小紅';
沒有錯,而且復合索引中的兩個索引字段都能很好的利用到了!因為語句中最左面的name字段進行了等值匹配,所以cid是有序的,也可以利用到索引了。
 
你可能會問:我建的索引是(name,cid)。而我查詢的語句是cid=1 AND name='小紅'; 我是先查詢cid,再查詢name的,不是先從最左面查的呀?
 
好吧,我再解釋一下這個問題:首先可以肯定的是把條件判斷反過來變成這樣 name='小紅' and cid=1; 最后所查詢的結果是一樣的。
那么問題產生了?既然結果是一樣的,到底以何種順序的查詢方式最好呢?
 
所以,而此時那就是我們的mysql查詢優化器該登場了,mysql查詢優化器會判斷糾正這條sql語句該以什么樣的順序執行效率最高,最后才生成真正的執行計划。所以,當然是我們能盡量的利用到索引時的查詢順序效率最高咯,所以mysql查詢優化器會最終以這種順序進行查詢執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM