sql優化(二)---- 索引(一)
---
title: 不懂SQL優化?那你就OUT了(二)
-- 索引(一)
date: 2018-10-27
categories: 數據庫優化
---
要想讓一個較慢的select ... where語句執行效率更快,我們應首先檢查是否能增加一個索引。不同表之間的引用通常通過索引來完成。你可以使用explain語句(上一篇已介紹)來確定select語句是否使用索引,使用了哪些索引。
索引
索引是一種特殊的文件,它們包含著對數據表裏所有記錄的引用指針。
它是對數據庫表中一列或多列的值進行排序的一種結構。
簡單理解就是:
數據庫索引好比是一本書前面的目錄,能夠加快數據庫的查詢速度.
數據庫索引就是為了提高表的搜索效率而對某些字段中的值建立的目錄。
為什麽要使用索引
創建索引可以大大提高系統的性能
1. 通過創建唯一索引,可以保證數據庫表中每一行數據的唯一性。
2. 可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
3. 可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
4. 顯著減少查詢中分組和排序的時間。
5. 通過使用索引,可以在查詢的過程中,使用優化器,提高系統的性能
索引的分類
索引的類型大體上可分為:
1. 普通索引
2. 唯一索引
3. 主鍵索引
4. 全文索引。
普通索引
普通索引有分為:單列索引 和 多列索引
1. 單列索引:就是一個索引只包含單個列,一個表可以有多個單列索引。
2. 多列索引:也稱組合索引,即一個索引包含多個列。
創建普通索引的語法
查看某張表的索引:show index from 表名;
創建普通索引:
1. create index 索引名 on 表名(表中加索引的列名)
2. alter table 表名 add index 索引名 (表中加索引的列)
3. create table 表名(
列名 列的數據類型 列的約束,
index 索引名(表中加索引的列)
)
創建多列索引:
1. create index 索引名 on 表名(表中加索引的列1,表中加索引的列2,...)
2. alter table 表名 add index 索引名 (表中加索引的列1,表中加索引的列2,...)
3. create table 表名(
列名 列的數據類型 列的約束,
index 索引名(表中加索引的列1,表中加索引的列2,...)
)
刪除某張表的索引:
drop index 索引名 ON 表名;
唯一索引
它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。
如果是組合索引,則列值的組合必須唯一
創建唯一索引語法
與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。
如果是組合索引,則列值的組合必須唯一.
語法:
1. create unique index 索引名 on 表名(表中加索引的列)
2. alter table 表名 add unique index 索引名 (表中加索引的列)
3. create table 表名(
列名 列的數據類型 列的約束,
unique index 索引名(表中加索引的列)
)
主鍵索引
它是一種特殊的唯一索引,不允許有空值。
創建主鍵索引的語法
語法:
1. alter table 表名 add primary key(列名)
2. create table 表名(
列名1 列的數據類型 列的約束(primary key),
列名2 列的數據類型 列的約束
)
全文索引
現在的互聯網上,很多網站都提供了全文搜索(全文檢索)功能,瀏覽者可以通過輸入關鍵字或者是短語來搜索特定的資料。
通常的做法是通過 select 查詢的 like 語句來進行搜索,這一辦法存在搜索不夠精確、以及效率非常低下的缺點。
mysql 提供了一個全文索引功能,也就是把字段設置上fullText索引屬性,然後通過select的match against語句進行查找。
mysql 支持全文索引和搜索功能,但是 fullText 索引僅能用於 myisam 引擎(數據庫引擎以後在介紹)的表。
myisam 引擎支持全文檢索(full text index),查詢效率高。但是有局限,不支持事務和外鍵。
創建全文索引的語法
語法:
1.Create fulltext index 索引名 on 表名(表中加索引的列)
2.alter table 表名 add fulltext index 索引名(表中加索引的列)
3. create table 表名(
列名 列的數據類型 列的約束,
fulltext 索引名(表中加索引的列)
)
案列
首先創建一個測試表: t_studentInfo
create table t_studentInfo(
-- 學生編號
studentId int primary key auto_increment, -- 創建了唯一索引(主鍵)
-- 學生姓名
studentName varchar(20)
-- 學生年齡
studentAge int,
-- 家庭住址
studentAddress varchar(255)
)engine=myisam,default charset=utf8
使用 存儲過程添加 1000萬條數據
DELIMITER $
CREATE PROCEDURE pro_datas()
BEGIN
DECLARE num INT;
DECLARE age INT;
DECLARE result INT;
DECLARE address VARCHAR(25);
SET num:=1;
WHILE num <= 10000000 DO
SET age:= 18+CEIL(RAND()*10);
SET result:=CEIL(RAND()*100);
IF result < 25 THEN
SET address:="成都市";
ELSEIF result<50 THEN
SET address:="綿陽市";
ELSEIF result<75 THEN
SET address:="昆明市";
ELSE
SET address:="貴陽市" ;
END IF;
INSERT INTO t_studentInfo(studentName,studentAge,studentAddress) VALUES(CONCAT(‘學生‘,num),age,address);
SET num=num+1;
END WHILE;
END $
在執行
CALL pro_datas();
執行時間:
添加1000萬條(在myisam引擎)數據花費了大約6分鐘。
執行sql :
select * from t_studentInfo where studentName="學生1024"
執行結果:
使用explain查看sql語句執行計劃
從執行計劃中可以看到,該查詢未使用索引,而是進行了全表掃描(type=all),並且掃描了1000萬條數據,效率低下。
現在為表的學生姓名列添加索引
我們看到添加時間大約4分鐘,建索引的過程會全表掃描,逐條建索引,當然慢了。
現在再次執行
select * from t_studentInfo where studentName="學生1024"
執行時間:
發現查詢效率快了很多。
查看添加索引後的執行計劃
可以從執行計劃中看到,此查詢使用索引(type=ref),使用了 idx_studentName 索引,並且只掃描了一條數據,效率甚高。
總結
索引的主要作用就是: 加快數據庫的查詢效率。
sql優化(二)---- 索引(一)