MySQL 索引
MySQL官方對索引的定義爲:索引是幫助MySQL高效獲取數據的數據結構。 提取句子主幹,就可以得到索引的本質:索引是數據結構。
1 索引的分類
一個表中主鍵索引只能有一個,唯一索引可能有多個
- 主鍵索引 (PRIMARY KEY)
- 唯一的標識,主鍵不可重複,只能有一個列作爲主鍵
- 唯一索引 (UNIQUE KEY)
- 避免重複的字段值出現,唯一索引可以重複(多個列都可標識爲唯一索引)
- 常規索引 (KEY/INDEX)
- 默認的,可以用INDEX/KEY 關鍵字來設置
- 全文索引 (FULLTEXT)
- 在特定的數據庫引擎下才有,MyISAM
- 快速定位數據
基礎語法:
-- 索引的使用
-- 1、在創建表的時候給字段增加索引
-- 2、創建完畢後,增加索引
-- 顯示所有的索引信息
SHOW INDEX FROM student
-- 增加一個全文索引 索引名 (列名)
ALTER TABLE `student` ADD FULLTEXT INDEX `Name`(`Name`)
-- EXPLAIN 分析sql執行的狀況
EXPLAIN SELECT * FROM student; -- 非全文索引
EXPLAIN SELECT * FROM student WHERE MATCH(`Name`) AGAINST('A')
2 測試索引
首先我們採用函數語句創建100萬條數據,代碼如下:
-- MySQL設置默認不允許創建函數,現採用臨時方案,重啓後恢復原狀
SET GLOBAL log_bin_trust_function_creators = 1;
-- 插入100萬條數據函數
DELIMITER $$ -- 寫函數之前必須寫,作爲標誌
CREATE FUNCTION mock_data()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i<num DO
-- 插入語句
INSERT INTO app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)
VALUES(CONCAT('用戶',i),'[email protected]',CONCAT('18',FLOOR(RAND()*999999999)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
SET i = i+1;
END WHILE;
RETURN i;
END;
SELECT mock_data(); -- 執行函數
現進行以下測試:
SELECT * FROM app_user WHERE `name` = '用戶9999'; -- 耗時接近500ms
EXPLAIN SELECT * FROM app_user WHERE `name` = '用戶9999';
-- id_表明_字段名
-- CREATE INDEX 索引名 ON 表(字段)
CREATE INDEX id_app_user_name ON app_user(`name`);
SELECT * FROM app_user WHERE `name` = '用戶9999'; -- 耗時小於0.1ms
EXPLAIN SELECT * FROM app_user WHERE `name` = '用戶9999'; -- 耗時小於0.1ms
結論: 索引在小數據量的時候,用戶不大,但是在大數據的時候,區別十分明顯!
3 索引原則
- 索引不是越多越好
- 不要對進程變動數據加索引
- 小數據量的表不需要加索引
- 索引一般加載常用來查詢的字段上!
索引的額數據結構
Hash 類型的索引
Btree:InnoDB的默認數據結構
建議閱讀一篇非常優質的博客:
http://blog.codinglabs.org/articles/theory-of-mysql-index.html
寫在最後
You will be free!
To Demut!