數據庫 = MySQL 索引以及原理

mysql索引:創建索引,創建索引原則,索引的數據結構,mysql數據存儲引擎

mysql性能

一.MySQL性能

(1)數據庫性能優化分爲兩種:硬優化,軟優化

分析--執行次數比較多的的語句:

=查詢密集型:我們使用查詢頻率較高,8:2左右

我們就可以使用索引來進行優化

=修改密集型

ES

--查詢累計插入 和 返回數據條數

show global status like 'Innodb_rows%';

(2)查看-sql語句的執行效率

插入千萬條記錄:

CREATE DATABASE crmproject;

USE crmproject;

-- 1. 準備表
CREATE TABLE `user`(
	id INT,
	username VARCHAR(32),
	`password` VARCHAR(32),
	sex VARCHAR(6),
	email VARCHAR(50)
);

-- 2. 創建存儲過程,實現批量插入記錄
DELIMITER $$ -- 聲明存儲過程的結束符號爲$$
CREATE PROCEDURE auto_insert()
BEGIN
    DECLARE i INT DEFAULT 1;
	START TRANSACTION; -- 開啓事務
    WHILE(i<=10000000)DO
        INSERT INTO `user` VALUES(i,CONCAT('ack',i),MD5(i),'male',CONCAT('ack',i,'wld.cn'));
        SET i=i+1;
    END WHILE;
	COMMIT; -- 提交
END$$ -- 聲明結束
DELIMITER ; -- 重新聲明分號爲結束符號

-- 3. 查看存儲過程
SHOW CREATE PROCEDURE auto_insert;

-- 4. 調用存儲過程
CALL auto_insert();

耗時非常大如下:

慢查詢日誌:

-- 查看慢查詢日誌開啓情況
show variables like '%slow_query_log%';

-- 查看慢查詢時間配置
show variables like '%long_query_time%';

查詢當前的慢日誌狀態
show variables like '%query%' ;
 
其中long_query_time表示執行時間比較長的記錄 slow_query_log=off 表示慢日誌爲關閉狀態,slow_query_log_file 表示慢日誌存儲的位置

開啓慢查詢日誌

set global slow_query_log = on;

設置慢查詢sql的時間閾值

-- 全局配置(下次生效...)
set global long_query_time=3;
-- 臨時(會話)配置(本次會話窗口生效)
set session long_query_time=3;

測試慢查詢日誌:

慢查詢日誌文件分析:

二,MySQL索引

(1)什麼是索引:將數據進行排序整理的過程就稱爲 索引

我們根據索引去查,提高效率

MySQL索引的建立對於MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。
 
(2)MySQL索引的分類

* 主鍵(約束)索引
        主鍵約束+提高查詢效率:加速查詢 + 列值唯一(不可以有null+ 表中只有一個 , 主鍵約束
        
* 唯一(約束)索引
        唯一約束+提高查詢效率:加速查詢 + 列值唯一(可以有null) 唯一約束

* 普通索引
        僅提高查詢效率

* 組合(聯合)索引
        多個字段組成索引:多列值組成一個索引,注意:最左匹配原則

* 全文索引
        solr、es

* hash索引
        根據key-value 效率非常高)

(3)MySQL索引語法

創建索引:

  • 直接創建:

-- 創建普通索引
create index 索引名 on 表名(字段);

-- 創建唯一索引
create unique index 索引名 on 表名(字段);

-- 創建普通組合索引
create index 索引名 on 表名(字段1,字段2);

-- 創建唯一組合索引
create unique index 索引名 on 表名(字段1,字段2);

-- 創建學生表
CREATE TABLE student(
 id INT,
 `name` VARCHAR(32),
 telephone VARCHAR(11)
);

-- name字段適合設置什麼索引?
CREATE INDEX name_idx ON student(`name`);

-- telephone適合設置什麼索引?
CREATE UNIQUE INDEX telephone_uni_idx ON student(telephone);
  • 修改表時創建

-- 添加一個主鍵,這意味着索引值必須是唯一的,且不能爲NULL
alter table 表名 add primary key(字段);  --默認索引名:primary

-- 添加唯一索引(除了NULL外,NULL可能會出現多次)
alter table 表名 add unique(字段); -- 默認索引名:字段名

-- 添加普通索引,索引值可以出現多次。
alter table 表名 add index(字段); -- 默認索引名:字段名

-- 指定id爲主鍵索引
ALTER TABLE student ADD PRIMARY KEY(id);
-- 指定name爲普通索引
ALTER TABLE student ADD INDEX(`name`);
-- 指定telephone爲唯一索引
ALTER TABLE student ADD UNIQUE(telephone);
  • 創建表時創建
-- 創建教師表
CREATE TABLE teacher(
 id INT PRIMARY KEY AUTO_INCREMENT, -- 主鍵索引
 `name` VARCHAR(32),
 telephone VARCHAR(11) UNIQUE, -- 唯一索引
 sex VARCHAR(5),
 birthday DATE,
 INDEX(`name`) -- 普通索引
);

刪除索引:

-- 直接刪除
drop index 索引名 on 表名;

-- 修改表時刪除
alter table 表名 drop index 索引名;

-- 刪除name普通索引
DROP INDEX name_idx ON student;

-- 刪除telephone唯一索引
ALTER TABLE student DROP INDEX telephone_uni_idx;

(4)千萬級表記錄效果演示:

測試沒有索引的情況下查詢

-- 1.指定id查詢
select * from user where id = 8888888;
-- 2.指定username精準查詢
select * from user  where username = 'jack1234567';
-- 3.指定email模糊查詢
select * from user  where email like 'jack1234567%';

給這三個字段添加索引:

-- 指定id爲主鍵索引
ALTER TABLE USER ADD PRIMARY KEY(id);
-- 指定username爲普通索引
ALTER TABLE USER ADD INDEX(username);
-- 指定email爲唯一索引
ALTER TABLE USER ADD UNIQUE(email);

在有索引的情況下查詢:

-- 1.指定id查詢
select * from user where id = 8888888;
-- 2.指定username精準查詢
select * from user  where username = 'jack1234567';
-- 3.指定email模糊查詢
select * from user  where email like 'jack1234567%';

(5)索引的優缺點:

優勢:

① 類似大學圖書館建書目索引,提高數據檢索的效率,降低數據庫的 IO 成本。 ② 通過索引列對數據
進行排序,降低數據排序的成本,降低 CPU 的消耗。
 

劣勢:

① 實際上索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄,所以索引列也是要佔用
空間的
② 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERTUPDATE
DELETE操作 , MySQL不僅要保存數據,還要更新一下索引文件 , 理論上來說 , 頻繁的更新索引字段的數
, 表的更新效率會下降
 
總結:
優點:減少磁盤IO,提高查詢效率
缺點:索引佔用磁盤空間
        我們在進行增刪改時,索引的維護會增加成本,可能會降低服務器性能

 

(6)索引創建的原則

1. 字段內容可識別度不能低於70%

2. 經常使用where條件搜索的字段

3. 經常使用表連接的字段(內連接、外連接)

4. 經常排序的字段 order by


* 注意:索引本身會佔用磁盤空間,不是所有的字段都適合增加索引....

(7)常見索引失效情況

-- 1.使用like模糊匹配,%通配符在最左側使用時
select * from user where email like '%jack1234567%';
-- 2.儘量避免使用or,如果條件有一個沒有索引,那麼會進行全表掃描
select * from user where id = 88 or sex = 'male';
-- 3.在索引列上進行計算
select * from user where  id+1 = 88;
-- 4.使用 !=、 not in、is not null時
select * from user where username != 'jack12';

(8)索引的數據結構

索引是幫助MySQL高效獲取排好序的數據結構

爲啥使用索引後查詢效率提高了很多呢?

在沒有索引的情況下我們執行一條sql語句,那麼是表進行全局遍歷,磁盤尋址(注意邏輯上相鄰的記錄在磁盤上也並不是一定物理相鄰的)。

select  * from user where col1=6;

爲了加快的查找效率,可以維護一個右邊所示的二叉查找樹,每個節點分別包含索引鍵值和一個指向對應數據記錄物理地址的指針,這樣就可以運用二叉查找快速獲取到相應數據。

select  * from user where col2=89;

索引的數據結構:

  • 二叉樹:左邊的子節點比父節點小,右邊的子節點比父節點大

  • 紅黑樹:平衡二叉樹(左旋、右旋)

1000w條記錄,使用紅黑樹,數的深(高)度

  • BTree:多路平衡搜索樹

  • B+Tree:優化BTree(非葉子節點:索引+指針、葉子節點:索引+數據【地址】)

  • Hash,通過散列算法,不支持範圍查詢

 

MySQL中的B+Tree

-- 查看mysql索引節點大小
show global status like 'innodb_page_size';

MySQL中的B+Tree索引結構示意圖

 

(9)索引的存儲引擎

MySQL存儲引擎的不同,那麼索引文件保存的方式也有所不同,常見的有二種存儲引擎MyISAMInnoDB

  • myisam(非聚集索引)

MySQL5.5版本之前默認存儲引擎 :特點:不支持事務、不支持外鍵約束

CREATE DATABASE crmpro;
USE crmpro;

-- 創建 myisam存儲引擎表
CREATE TABLE tab_myisam(
 id INT,
 `name` VARCHAR(32)
)ENGINE=MYISAM;

  • InnoDB(聚集索引)

MySQL5.5版本之後默認存儲引擎 :特點:支持事務、支持外鍵約束

-- 創建 innodb存儲引擎表
CREATE TABLE tab_innodb(
 id INT,
 `name` VARCHAR(32)
)ENGINE = INNODB;

innodb存儲引擎必須要設置主鍵(整型),且自增類型....

 

資料:

算法演示網站

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章