MySQL——效能優化

yshir-phper發表於2020-11-18

效能優化的思路

1、首先需要使用慢查詢功能,去獲取所有查詢時間比較長的SQL語句。
MySQL——慢查詢
2、其次使用explain命令去檢視有問題的SQL的執行計劃。
MySQL——執行計劃EXPLAIN
3、最後可以使用show profile[s] 檢視有問題的SQL的效能使用情況。
MySQL高階:show profile

SQL查詢語法順序和執行順序

MySQL查詢語法順序

  • SELECT
  • FROM
  • LEFT JOIN
  • ON
  • WHERE
  • GROUP BY
  • HAVING
  • ORDER BY
  • LIMIT

MySQL查詢執行順序

示例SQL

  SELECT * FROM user LEFT JOIN order ON user.id = order.uid WHERE order.price > 1000 GROUP BY user.name HAVING count(1) > 5 ORDER BY user.name LIMIT 0,10

1、FROM(將最近的兩張表,進行笛卡爾積)—VT1
2、ON(將VT1按照它的條件進行過濾)—VT2
3、LEFT JOIN(保留左表的記錄)—VT3
4、WHERE(過濾VT3中的記錄)–VT4…VTn
5、GROUP BY(對VT4的記錄進行分組)—VT5
6、HAVING(對VT5中的記錄進行過濾)—VT6
7、SELECT(對VT6中的記錄,選取指定的列)–VT7
8、ORDER BY(對VT7的記錄進行排序)–遊標
9、LIMIT(對排序之後的值進行分頁)

WHERE條件執行順序(影響效能)
1、MYSQL:從左往右去執行WHERE條件的。
2、Oracle:從右往左去執行WHERE條件的。

結論:寫WHERE條件的時候,優先順序高的部分要去編寫過濾力度最大的條件語句。
語法樹
SQL解析在美團的應用

MySQL效能優化細節

1、合理的建立及使用索引(考慮資料的增刪情況)。
2、合理的冗餘欄位(儘量建一些大表,考慮資料庫的三正規化和業務設計的取捨)。
3、使用SQL要注意一些細節:
select語句中儘量不要使用*、count(*),
WHERE語句中儘量不要使用1=1、in語句(建議使用exists)、
注意組合索引的建立順序按照順序組著查詢條件、
儘量查詢粒度大的SQL放到最左邊、
儘量建立組合索引。
4、合理利用慢查詢日誌、explain執行計劃查詢、show profile檢視SQL執行時的資源使用情況。

5、表關聯查詢時務必遵循小表驅動大表原則。
6、使用查詢語 where 條件時,不允許出現函式,否則索引會失效;
7、使用單表查詢時,相同欄位儘量不要用 OR,因為可能導致索引失效,比如:SELECT * FROM table WHERE name = '手機' OR name = '電腦',可以使用 UNION 替代;
8、LIKE 語句不允許使用 % 開頭,否則索引會失效;
9、組合索引一定要遵循 從左到右 原則,否則索引會失效;比如:SELECT * FROM table WHERE name = '張三' AND age = 18,那麼該組合索引必須是 name,age 形式;
10、索引不宜過多,根據實際情況決定,儘量不要超過 10 個;
11、每張表都必須有 主鍵,達到加快查詢效率的目的;
12、分表,可根據業務欄位尾數中的個位或十位或百位(以此類推)做表名達到分表的目的;
13、分庫,可根據業務欄位尾數中的個位或十位或百位(以此類推)做庫名達到分庫的目的;
14、表分割槽,類似於硬碟分割槽,可以將某個時間段的資料放在分割槽裡,加快查詢速度,可以配合 分表 + 表分割槽 結合使用;

索引相關

最左字首匹配原則

在mysql建立聯合索引時會遵循最左字首匹配的原則,即最左優先,在檢索資料時從聯合索引的最左邊開始匹配,示例:
對列col1、列col2和列col3建一個聯合索引

KEY test_col1_col2_col3 on test(col1,col2,col3);

聯合索引 test_col1_col2_col3 實際建立了(col1)、(col1,col2)、(col,col2,col3)三個索引。

SELECT * FROM test WHERE col1='1' AND clo2='2' AND clo4='4'

上面這個查詢語句執行時會依照最左字首匹配原則,檢索時會使用索引(col1,col2)進行資料匹配。

為什麼要使用聯合索引

減少開銷。建一個聯合索引(col1,col2,col3),實際相當於建了(col1),(col1,col2),(col1,col2,col3)三個索引。每多一個索引,都會增加寫操作的開銷和磁碟空間的開銷。對於大量資料的表,使用聯合索引會大大的減少開銷!

覆蓋索引。對聯合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那麼MySQL可以直接通過遍歷索引取得資料,而無需回表,這減少了很多的隨機io操作。減少io操作,特別的隨機io其實是dba主要的優化策略。所以,在真正的實際應用中,覆蓋索引是主要的提升效能的優化手段之一

效率高。索引列越多,通過索引篩選出的資料越少。有1000W條資料的表,有如下sql:select from table where col1=1 and col2=2 and col3=3,假設假設每個條件可以篩選出10%的資料,如果只有單值索引,那麼通過該索引能篩選出1000W10%=100w條資料,然後再回表從100w條資料中找到符合col2=2 and col3= 3的資料,然後再排序,再分頁;如果是聯合索引,通過索引篩選出1000w10% 10% *10%=1w,效率提升可想而知!

相關文章