思路:
- 通過慢查詢日誌去尋找哪些 SQL 執行效率低
- 使用 explain 獲取低效率 SQL 的執行計劃
- 結合 SQL 與執行計劃,進行分析與優化
引起 SQL 查詢很慢的原因與解決辦法:
1、沒有索引。解決辦法:
- 根據 where 和 order by 使用比較頻繁的字段創建索引,提高查詢效率
- 索引不宜過多,單表最好不要超過 6 個。索引過多會導致佔用存儲空間變大;insert、update 變慢
- 刪除未使用的索引
2、索引未生效。解決辦法:
- 避免在 where 子句中對字段進行 null 值判斷,創建表默認值是 NULL。儘量使用 NOT NULL,或使用特殊值,如 0、-1
- 避免在 where 子句中使用 != 或 <> 操作符, MySQL 只有對以下操作符才使用索引:<、<=、=、>、>=、BETWEEN、IN、非 % 開頭的 LIKE
- 避免在 where 子句中使用 or 來連接條件,可以使用 UNION 進行連接
- 能用 union all 就不用 union,union 過濾重複數據要耗費更多的 CPU 資源
- 避免部分 like 查詢,如 '%ConstXiong%'
- 避免在索引列上使用計算、函數
- in 和 not in 慎用,能用 between 不要用 in
- select 子句中避免使用 *
3、單表數據量太大。解決辦法:
- 分頁查詢(在索引上完成排序分頁操作、藉助主鍵進行關聯)
- 單表數據過大,進行分庫分表
- 考慮使用非關係型數據庫提高查詢效率
- 全文索引場景較多,考慮使用 ElasticSearch、solr
提升性能的一些技巧:
- 儘量使用數字型字段
- 只需要一行數據時使用 limit 1
- 索引儘量選擇較小的列
- 不需要的數據在 GROUP BY 之前過濾掉
- 大部分時候 exists、not exists 比 in、not in 效率(除了子查詢是小表的情況使用 in 效率比 exists 高)
- 不確定長度的字符串字段使用 varchar/nvarchar,如使用 char/nchar 定長存儲會帶來空間浪費
- 不要使用 select *,去除不需要的字段查詢
- 避免一次性查詢過大的數據量
- 使用表別名,減少多表關聯解析時間
- 多表 join 最好不超過 5 個,視圖嵌套最好不超過 2 個
- or 條件查詢可以拆分成 UNION 多個查詢
- count(1) 比 count(*) 有效
- 判斷是否存在數據使用 exists 而非 count,count 用來獲取數據行數
【Java面試題與答案】整理推薦