六、mysql性能優化

一、慢查詢

1、慢查詢日誌

是指 mysql 記錄所有執行超過long_query_time參數設定的時間閾值的 SQL 語句的日誌。

2、慢查詢配置

# 默認 10 秒,這裏爲了演示方便設置爲 0 
set global long_query_time=0;
#W開啓慢查詢日誌
set GLOBAL slow_query_log = 1; 
# 項目開發中日誌只能記錄在日誌文件中,不能記表中
set global log_output='FILE,TABLE' 
# 查看慢查詢日誌信息
cat /usr/local/mysql/data/mysql-slow.log

3、慢查詢日誌解析

在這裏插入圖片描述

  • 第一行:用戶名 、用戶的 IP 信息、線程 ID 號
  • 第二行:執行花費的時間【單位:毫秒】
  • 第三行:執行獲得鎖的時間
  • 第四行:獲得的結果行數
  • 第五行:掃描的數據行數
  • 第六行:這 SQL 執行的具體時間
  • 第七行:具體的 SQL 語句

4、慢查詢分析

慢查詢的日誌記錄非常多,要從裏面找尋一條查詢慢的日誌並不是很容易的事情,一般來說都需要一些工具輔助才能快速定位到需要優化的 SQL 語句。

4.1Mysqldumpshow

mysqldumpshow -s r -t 10 slow-mysql.log
 -s order (c,t,l,r,at,al,ar)
c:總次數
t:總時間
l:鎖的時間
r:總數據行
at,al,ar :t,l,r 平均數 【例如:at = 總時間/總次數】
-t top 指定取前面幾條作爲結果輸出

# 按照時間排序,取出前10條記錄
mysqldumpslow -s t -t 10 /usr/local/mysql/data/mysql-slow.log

在這裏插入圖片描述

二、索引

1、mysql索引B+tree

1.1定義

  • 數據只存儲在葉子節點上,非葉子節點只保存索引信息;
    ◦ 非葉子節點(索引節點)存儲的只是一個 Flag,不保存實際數據記錄;
    ◦ 索引節點指示該節點的左子樹比這個 Flag 小,而右子樹大於等於這個 Flag
  • 葉子節點本身按照數據的升序排序進行鏈接(串聯起來);
    ◦ 葉子節點中的數據在 物理存儲上是無序 的,僅僅是在 邏輯上有序 (通過指針串在一起);

1.2 作用

  • 在塊設備上,通過B+樹可以有效的存儲數據;
  • 所有記錄都存儲在葉子節點上,非葉子(non-leaf)存儲索引(keys)信息;
  • B+樹含有非常高的扇出(fanout),通常超過100,在查找一個記錄時,可以有效的減少IO操作;

1.3B+tree操作

B+tree操作

2、索引分類

  • 普通索引:即一個索引只包含單個列,一個表可以有多個單列索引
  • 唯一索引:索引列的值必須唯一,但允許有空值 複合索引:即一個索引包含多個列
  • 聚簇索引(聚集索引):並不是一種單獨的索引類型,而是一種數據存儲方式。具體細節取決 於不同的實現,InnoDB 的聚簇索引其實就是在同一個結構中保存了 B-Tree 索引(技術上來說 是B+Tree)和數據行。
  • 非聚簇索引:不是聚簇索引,就是非聚簇索引
# 查看索引
SHOW INDEX FROM table_name\G
# 創建索引
CREATE [UNIQUE ] INDEX indexName ON mytable(columnname(length));
ALTER TABLE 表名 ADD [UNIQUE ] INDEX [indexName] ON (columnname(length))
# 刪除索引
DROP INDEX [indexName] ON mytable;

三、執行計劃

使用 EXPLAIN 關鍵字可以模擬優化器執行 SQL 查詢語句,從而知道 MySQL 是 如何處理你的 SQL 語句的。分析你的查詢語句或是表結構的性能瓶頸。

1、執行計劃詳解

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

四、sql優化

1、儘量全值匹配

當建立了索引列後,能在 wherel 條件中使用索引的儘量所用。
在這裏插入圖片描述

2、最佳坐前綴原則法則

如果索引了多列,要遵守最左前綴法則。指的是查詢從索引的最左前列開始並且不跳過索引中的列。
在這裏插入圖片描述

3、不在索引列上做任何操作

不在索引列上做任何操作(計算、函數、(自動 or 手動)類型轉換),會導致索引失效而轉向 全表掃描
在這裏插入圖片描述

4、範圍條件放最後

中間有範圍查詢會導致後面的索引列全部失效
在這裏插入圖片描述

5、覆蓋索引儘量用

在這裏插入圖片描述

6不等於要甚用

mysql 在使用不等於(!= 或者<>)的時候無法使用索引會導致全表掃描,如果定要需要使用不等於,請用覆蓋索引
在這裏插入圖片描述

7、Null/Not 有影響

  • 在字段爲 not null 的情況下,使用 is null 或 is not null 會導致索引失效
  • 自定義爲NULL或者不定義,Is not null 的情況會導致索引失效

解決方式:覆蓋索引

8Like 查詢要當心

like 以通配符開頭(’%abc…’)mysql 索引失效會變成全表掃描的操作
在這裏插入圖片描述

解決方式:覆蓋索引
EXPLAIN select name,age,pos from staffs where name like ‘%july%’

9、字符類型加引號

字符串不加單引號索引失效

10、OR改UNION效率高

# 索引失效
EXPLAIN
select * from staffs where name='July' or name = 'z3'

EXPLAIN
select * from staffs where name='July' UNION
select * from staffs where name = 'z3'

解決方式:覆蓋索引

EXPLAIN
select name,age from staffs where name='July' or name = 'z3'

解決方式:覆蓋索引

EXPLAIN
select name,age from staffs where name='July' or name = 'z3'

在這裏插入圖片描述

記憶總結:

  • 全職匹配我最愛,最左前綴要遵守;
  • 帶頭大哥不能死,中間兄弟不能斷;  索引列上少計算,範圍之後全失效;
  • LIKE百分寫最右,覆蓋索引不寫*;
  • 不等空值還有OR,索引影響要注意;
  • VAR 引號不可丟, SQL 優化有訣竅。

五、批量導入

LOAD DATA INFLIE
使用 LOAD DATA INFLIE ,比一般的 insert 語句快 20 倍

// 將product_info數據導出
select * into OUTFILE 'D:\\product.txt' from product_info
// 導入到product_info2中
load data INFILE 'D:\\product.txt' into table product_info2
load data INFILE '/soft/product3.txt' into table product_info2

200萬條數據,17s

show VARIABLES like 'secure_file_priv'
  • secure_file_priv 爲 NULL 時,表示限制 mysqld 不允許導入或導出。
  • secure_file_priv 爲 /tmp 時,表示限制 mysqld 只能在/tmp 目錄中執行導入導出,其他目錄不能執行。
  • secure_file_priv沒有值時,表示不限制mysqld在任意目錄的導入導出。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章