1. 程式人生 > >Mysql索引整理總結

Mysql索引整理總結

一、索引概述

1. 簡介

索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。

舉例說明索引:如果把資料庫中的某一張看成一本書,那麼索引就像是書的目錄,可以通過目錄快速查詢書中指定內容的位置,對於資料庫表來說,可以通過索引快速查詢表中的資料。

2. 索引的原理

索引一般以檔案形式存在磁碟中(也可以存於記憶體中),儲存的索引的原理大致概括為以空間換時間,資料庫在未新增索引的時候進行查詢預設的是進行全量搜尋,也就是進行全域性掃描,有多少條資料就要進行多少次查詢,然後找到相匹配的資料就把他放到結果集中,直到全表掃描完。而建立索引之後,會將建立索引的KEY值放在一個n叉樹上(BTree)。因為B樹的特點就是適合在磁碟等直接儲存裝置上組織動態查詢表,每次以索引進行條件查詢時,會去樹上根據key值直接進行搜尋。

3. 索引的優點

建立索引的目的是加快對錶中記錄的查詢或排序!

① 建立索引的列可以保證行的唯一性,生成唯一的rowId

② 建立索引可以有效縮短資料的檢索時間

③ 建立索引可以加快表與表之間的連線

④ 為用來排序或者是分組的欄位新增索引可以加快分組和排序順序

4. 索引的缺點

① 建立索引和維護索引需要時間成本,這個成本隨著資料量的增加而加大

② 建立索引和維護索引需要空間成本,每一條索引都要佔據資料庫的物理儲存空間,資料量越大,佔用空間也越大(資料表佔據的是資料庫的資料空間)

③ 會降低表的增刪改的效率,因為每次增刪改索引需要進行動態維護,導致時間變長

二、索引的使用場景

資料庫中表的資料量較大的情況下,對於查詢響應時間不能滿足業務需求,可以合理的使用索引提升查詢效率。

三、索引的分類和建立和修改刪除等命令

1. 基本索引型別

① 普通索引(單列索引)

② 複合索引(組合索引)

③ 唯一索引

④ 主鍵索引

⑤ 全文索引

2. 建立的語句

CREATE TABLE table_name[col_name data type]
[unique|fulltext][index|key][index_name](col_name[length])[asc|desc]
  • unique|fulltext為可選引數,分別表示唯一索引、全文索引

  • index和key為同義詞,兩者作用相同,用來指定建立索引

  • col_name為需要建立索引的欄位列,該列必須從資料表中該定義的多個列中選擇

  • index_name指定索引的名稱,為可選引數,如果不指定,預設col_name為索引值

  • length為可選引數,表示索引的長度,只有字串型別的欄位才能指定索引長度

  • asc或desc指定升序或降序的索引值儲存

3. 索引的建立、查詢和刪除

索引的建立

① 普通索引(單列索引)

普通索引(單列索引):單列索引是最基本的索引,它沒有任何限制。

(1)直接建立索引

CREATE INDEX index_name ON table_name(col_name);

(2)修改表結構的方式新增索引

ALTER TABLE table_name ADD INDEX index_name(col_name);

(3)建立表的時候同時建立索引

CREATE TABLE `news` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` varchar(255)  NOT NULL ,
    `content` varchar(255)  NULL ,
    `time` varchar(20) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    INDEX index_name (title(255))
)

(4)刪除索引

DROP INDEX index_name ON table_name;
或者
alter table `表名` drop index 索引名;

② 複合索引(組合索引)

複合索引:複合索引是在多個欄位上建立的索引。複合索引遵守“最左字首”原則即在查詢條件中使用了複合索引的第一個欄位,索引才會被使用。因此,在複合索引中索引列的順序至關重要。

(1)建立一個複合索引

create index index_name on table_name(col_name1,col_name2,...);

(2)修改表結構的方式新增索引

alter table table_name add index index_name(col_name,col_name2,...);

③ 唯一索引

唯一索引:唯一索引和普通索引類似,主要的區別在於,唯一索引限制列的值必須唯一,但允許存在空值(只允許存在一條空值)

如果在已經有資料的表上新增唯一性索引的話:
- 如果新增索引的列的值存在兩個或者兩個以上的空值,則不能建立唯一性索引會失敗。(一般在建立表的時候,要對自動設定唯一性索引,需要在欄位上加上 not null)
- 如果新增索引的列的值存在兩個或者兩個以上的null值,還是可以建立唯一性索引,只是後面建立的資料不能再插入null值 ,並且嚴格意義上此列並不是唯一的,因為存在多個null值。

對於多個欄位建立唯一索引規定列值的組合必須唯一。
比如:在order表建立orderId欄位和 productId欄位 的唯一性索引,那麼這兩列的組合值必須唯一!


“空值” 和”NULL”的概念: 
1:空值是不佔用空間的 .
2: MySQL中的NULL其實是佔用空間的.

長度驗證:注意空值的之間是沒有空格的。

> select length(''),length(null),length(' ');
+------------+--------------+-------------+
| length('') | length(null) | length(' ') |
+------------+--------------+-------------+
|          0 |         NULL |           1 |
+------------+--------------+-------------+

(1)建立唯一索引

# 建立單個索引
CREATE UNIQUE INDEX index_name ON table_name(col_name);

# 建立多個索引
CREATE UNIQUE INDEX index_name on table_name(col_name,...);

(2)修改表結構

# 單個
ALTER TABLE table_name ADD UNIQUE index index_name(col_name);
# 多個
ALTER TABLE table_name ADD UNIQUE index index_name(col_name,...);

(3)建立表的時候直接指定索引

CREATE TABLE `news` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` varchar(255)  NOT NULL ,
    `content` varchar(255)  NULL ,
    `time` varchar(20) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    UNIQUE index_name_unique(title)
)

④ 主鍵索引

主鍵索引是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值。一般是在建表的時候同時建立主鍵索引:

(1)主鍵索引(建立表時新增)


CREATE TABLE `news` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` varchar(255)  NOT NULL ,
    `content` varchar(255)  NULL ,
    `time` varchar(20) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`)
)

(2)主鍵索引(建立表後新增)

alter table tbl_name add primary key(col_name);

CREATE TABLE `order` (
    `orderId` varchar(36) NOT NULL,
    `productId` varchar(36)  NOT NULL ,
    `time` varchar(20) NULL DEFAULT NULL
)

alter table `order` add primary key(`orderId`);

⑤ 全文索引

在一般情況下,模糊查詢都是通過 like 的方式進行查詢。但是,對於海量資料,這並不是一個好辦法,在 like “value%” 可以使用索引,但是對於 like “%value%” 這樣的方式,執行全表查詢,這在資料量小的表,不存在效能問題,但是對於海量資料,全表掃描是非常可怕的事情,所以 like 進行模糊匹配效能很差。

這種情況下,需要考慮使用全文搜尋的方式進行優化。全文搜尋在 MySQL 中是一個 FULLTEXT 型別索引。FULLTEXT 索引在 MySQL 5.6 版本之後支援 InnoDB,而之前的版本只支援 MyISAM 表

全文索引主要用來查詢文字中的關鍵字,而不是直接與索引中的值相比較。fulltext索引跟其它索引大不相同,它更像是一個搜尋引擎,而不是簡單的where語句的引數匹配。fulltext索引配合match against操作使用,而不是一般的where語句加like。目前只有char、varchar,text 列上可以建立全文索引。

小技巧:
在資料量較大時候,先將資料放入一個沒有全域性索引的表中,然後再用CREATE index建立fulltext索引,要比先為一張表建立fulltext然後再將資料寫入的速度快很多。

(1)建立表的適合新增全文索引

CREATE TABLE `news` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` varchar(255)  NOT NULL ,
    `content` text  NOT NULL ,
    `time` varchar(20) NULL DEFAULT NULL ,
     PRIMARY KEY (`id`),
    FULLTEXT (content)
)

(2)修改表結構新增全文索引

ALTER TABLE table_name ADD FULLTEXT index_fulltext_content(col_name)

(3)直接建立索引

CREATE FULLTEXT INDEX index_fulltext_content ON table_name(col_name)

注意: 預設 MySQL 不支援中文全文檢索!

MySQL 全文搜尋只是一個臨時方案,對於全文搜尋場景,更專業的做法是使用全文搜尋引擎,例如 ElasticSearch 或 Solr。

索引的查詢和刪除

#檢視:
show indexes from `表名`;
#或
show keys from `表名`;

#刪除
alter table `表名` drop index 索引名;

注:MySQl的客戶端工具也可以進索引的建立、查詢和刪除,如 Navicat Premium!

四、簡單例項演示

檢視索引使用情況

show status like ‘Handler_read%’;

handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數
handler_read_rnd_next:這個值越高,說明查詢低效

常見索引失效的情況:

建立一個students表:
其中stud_id為主鍵!

DROP TABLE IF EXISTS `students`;
CREATE TABLE `students` (
  `stud_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `email` varchar(50) NOT NULL,
  `phone` varchar(1) NOT NULL,
  `create_date` date DEFAULT NULL,
  PRIMARY KEY (`stud_id`)

)

INSERT INTO `learn_mybatis`.`students` (`stud_id`, `name`, `email`, `phone`, `create_date`) VALUES ('1', 'admin', '[email protected]', '18729902095', '1983-06-25');
INSERT INTO `learn_mybatis`.`students` (`stud_id`, `name`, `email`, `phone`, `create_date`) VALUES ('2', 'root', '[email protected]', '2', '1983-12-25');
INSERT INTO `learn_mybatis`.`students` (`stud_id`, `name`, `email`, `phone`, `create_date`) VALUES ('3', '110', '[email protected]', '3dsad', '2017-04-28');
1. 在where後使用or,導致索引失效(儘量少用or)

簡單例項演示:
建立兩個普通索引,

CREATE INDEX index_name_email ON students(email);
CREATE INDEX index_name_phone ON students(phone);

使用下面查詢sql,

# 使用了索引
EXPLAIN select * from students where stud_id='1'  or phone='18729902095'
# 使用了索引
EXPLAIN select * from students where stud_id='1'  or email='[email protected]'

#--------------------------

# 沒有使用索引
EXPLAIN select * from students where phone='18729902095' or email='[email protected]'

# 沒有使用索引
EXPLAIN select * from students where stud_id='1'  or phone='222' or email='[email protected]'

2.使用like ,like查詢是以%開頭

在1的基礎上,還是使用 index_name_email 索引。

使用下面查詢sql

# 使用了index_name_email索引
EXPLAIN select * from students where email like '[email protected]%'

# 沒有使用index_name_email索引,索引失效
EXPLAIN select * from students where email like '%[email protected]'

# 沒有使用index_name_email索引,索引失效
EXPLAIN select * from students where email like '%[email protected]%'
3.複合索引遵守“最左字首”原則,即在查詢條件中使用了複合索引的第一個欄位,索引才會被使用

刪除1的基礎建立的 index_name_email 和 index_name_phone 索引。

重新建立一個複合索引:

create index index_email_phone on students(email,phone);

使用下面查詢sql

# 使用了 index_email_phone 索引
EXPLAIN select * from students where email='[email protected]' and  phone='18729902095'

# 使用了 index_email_phone 索引
EXPLAIN select * from students where phone='18729902095' and  email='[email protected]'

# 使用了 index_email_phone 索引
EXPLAIN select * from students where email='[email protected]' and name='admin'

# 沒有使用index_email_phone索引,複合索引失效
EXPLAIN select * from students where phone='18729902095' and name='admin'
4. 如果列型別是字串,那一定要在條件中將資料使用引號引用起來,否則不使用索引

給name建立一個索引!

CREATE INDEX index_name ON students(name);

# 使用索引
EXPLAIN select * from students where name='110'

# 沒有使用索引
EXPLAIN select * from students where name=110
5. 使用in導致索引失效
# 使用索引
EXPLAIN select * from students where name='admin'

# 沒有使用索引
EXPLAIN SELECT * from students where name in ('admin')
6. DATE_FORMAT()格式化時間,格式化後的時間再去比較,可能會導致索引失效。

刪除 students 上的建立的索引!重新在create_date建立一個索引!

CREATE INDEX index_create_date ON students(create_date);

# 使用索引
EXPLAIN SELECT * from students where create_date >= '2010-05-05'

# 沒有使用索引
EXPLAIN SELECT * from students where DATE_FORMAT(create_date,'%Y-%m-%d') >= '2010-05-05'

7. 對於order by、group by 、 union、 distinc 中的欄位出現在where條件中時,才會利用索引!
8. 更多索引的使用注意可以參看這一篇博文:

五、總結

MySQL改善查詢效能改善的最好方式,就是通過資料庫中合理地使用索引!

一般當資料量較大的時候,遇到sql查詢效能問題,首先想到的應該是查詢的sql時候使用了索引,如果使用了索引效能還是提高不大,就要檢查索引是否使用正確,索引是否在sql查詢中生效了!

如果索引生效了,並且索引的使用也是合理的,最後sql效能還是不高,那就考慮重新優化sql語句!

六、參考博文

七 拓展閱讀

如果您覺得這篇博文對你有幫助,請點贊或者喜歡,讓更多的人看到,謝謝!

如果帥氣(美麗)、睿智(聰穎),和我一樣簡單善良的你看到本篇博文中存在問題,請指出,我虛心接受你讓我成長的批評,謝謝閱讀!
祝你今天開心愉快!

歡迎訪問我的csdn部落格,我們一同成長!

不管做什麼,只要堅持下去就會看到不一樣!在路上,不卑不亢!

相關推薦

Mysql索引整理總結

一、索引概述 1. 簡介 索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。 舉例說明索引:如果把資料庫中的某一張看成一本書,那麼索引就像是書的目錄,可以通過目錄快速查詢書中指定內容的位置,對於資料庫表來說,可

MySql索引學習總結

常用 gin 深入 其中 條件 講解 成本 搜索 速查 1、索引是什麽   索引(Index)是幫助MySQL高效獲取數據的數據結構。可以得到索引的本質:索引是數據結構。   可以理解為“排好序的快速查找數據結構”   在數據之外,數據庫系統還維護著滿足特定查找算法的數據結

PHP------MySQL索引常用總結

MySQL索引: 索引就像書的目錄,能更快的找到內容,但是目錄也會佔用紙張,而索引會佔用磁碟空間。 索引結構 B+樹 B+樹是MySQL使用最頻繁的一個索引資料結構,資料結構一平衡樹的形式來組織。適合處理排序、範圍查詢等功能。相對hash索引,B+樹查詢單條資料

MySQL索引型別總結和使用技巧以及注意事項

在資料庫表中,對欄位建立索引可以大大提高查詢速度。假如我們建立了一個 mytable表: 複製程式碼程式碼如下: CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL  ); 我們隨機向裡面插入了100

MySQL索引使用總結--索引建立方法CREATE INDEX與ALTER TABLE的區別

MySQL中建立索引的兩種方式 CREATE INDEX index_name ON table_1(filed_1); ALTER TABLE table_1 ADD INDEX(fiel

Mysql索引整理

MySQL中索引的優點和缺點和使用原則 優點: 1、所有的MySql列型別(欄位型別)都可以被索引,也就是可以給任意欄位設定索引 2、大大加快資料的查詢速度 缺點: 1、建立索引和維護索引要耗費時間,並且隨著資料量的增加所耗費的時間也會增加 2、索引

MySQL索引及查詢優化總結

存儲 一行 -1 type 一定的 關鍵技術 表示 智能 string類型 一個簡單的對比測試 前面的案例中,c2c_zwdb.t_file_count表只有一個自增id,FFileName字段未加索引的sql執行情況如下: 在上圖中,type=all,key=nul

mysql索引總結

不同 正在 鍵值 tex nbsp 由於 5.0 不一定 red 今天抽空整理了下mysql的幾種索引類型,以備加深印象: 在MySQL 中,主要有四種類型的索引,分別為:B-Tree 索引,Hash 索引,Fulltext 索引和RTree索引 1、B-Tree 索引

mysql索引總結(3)-MySQL聚簇索引和非聚簇索引

部分 inno ext 找到 存儲位置 sso 影響 直接 支持 非聚簇索引 索引節點的葉子頁面就好比一片葉子。葉子頭便是索引鍵值。 先創建一張表: CREATE TABLE `user` ( `id` INT NOT NULL , `name` VARCHAR NOT

MySQL索引類型總結和使用技巧

創建 cit city 不同的 多個 int pos join 必須 引用地址:http://www.jb51.net/article/49346.htm 在數據庫表中,對字段建立索引可以大大提高查詢速度。假如我們創建了一個 mytable表: 復制代碼 代碼如下: C

MySQL後臺線程整理總結

thread類 刪除 有關 mod 交互 per 模式 span pan 本文整理自《MySQL技術內幕 InnoDB存儲引擎》 MySQL通過後臺各種線程、內存池、文件交互來實現對外服務的,不同線程實現不同的資源操作,各個線程相互協助,共同來完成數據庫的服務。以

mysql的主鍵和索引總結

1、mysql的主鍵和外來鍵的區別 主鍵是用來唯一標識表中一條記錄的。 主鍵不允許為null 主鍵是唯一的 一個表只能有一個主鍵。 外來鍵是在兩個表之間建立連線的,一個表可以有一個或者多個外來鍵,外來鍵主要作用是保證資料引用的完整性 可以允許為null,若是不為null的話,則必須是子表的主

MySQL索引總結以及執行索引語句

例如:資料庫中2萬條記錄,如果要執行一個查詢,select  * from table where num =1000, 如果沒有建立索引,必須要遍歷整個表,直到num=1000被找到為止, 如果在num這個列上設定索引,就不需要任何的掃描,直接在索引裡面找到1000. 所以建

MySQL索引優化步驟總結

在專案使用mysql過程中,隨著系統的執行,發現一些慢查詢,在這裡總結一下mysql索引優化步驟 1.開發過程優化 開發過程中對業務表中查詢sql分析sql執行計劃(尤其是業務流水錶),主要是檢視sql執行計劃,對sql進行優化。 explain執行計劃關鍵屬性 select_type,possibl

MySQL索引擴充套件(Index Extensions)學習總結

mysql> SET optimizer_switch = 'use_index_extensions=on';Query OK, 0 rows affected (0.00 sec)mysql> FLUSH TABLE t1;Query OK, 0 rows affected (0.00 sec

MySQL後臺執行緒整理總結

 本文整理自《MySQL技術內幕 InnoDB儲存引擎》 MySQL通過後臺各種執行緒、記憶體池、檔案互動來實現對外服務的,不同執行緒實現不同的資源操作,各個執行緒相互協助,共同來完成資料庫的服務。以下簡單總結MySQL的一些後臺執行緒以及主要作用,以及innodb引擎的變化升級情況。 整體上看,My

mysql索引總結----mysql 索引型別以及建立

文章歸屬:http://feiyan.info/16.html 關於MySQL索引的好處,如果正確合理設計並且使用索引的mysql是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是一個人力三輪車。對於沒有索引的表,單表查詢可能幾十萬資料就是瓶頸,而通

MySQL 索引及查詢優化總結

本文由雲+社群發表 文章《MySQL查詢分析》講述了使用MySQL慢查詢和explain命令來定位mysql效能瓶頸的方法,定位出效能瓶頸的sql語句後,則需要對低效的sql語句進行優化。本文主要討論MySQL索引原理及常用的sql查詢優化。 一個簡單的對比測試 前面的案例中,c2c_zwdb

MySQL索引優化策略-論壇經典例項整理

二.索引優化策略索引型別1.B-tree索引注:名叫btree索引,大的方面看,都用的平衡樹,但具體的實現上,各引擎稍有不同。比如嚴格的說NDB引擎使用的是T-treeMyisam,innodb中預設用B-tree索引B-tree系統抽象一下,可以理解為“排好序的快速查詢結構

資料庫索引(Oracle和Mysql)學習總結

索引概念:     索引是關係資料庫中用於存放每一條記錄的一種物件,主要目的是加快資料的讀取速度和完整性檢查。建立索引是一項技術性要求高的工作。一般在資料庫設計階段的與資料庫結構一道考慮。應用系統的效能直接與索引的合理直接有關。 一、Oracle索引 1、索引型別 列