前言
本文介紹一些常見的性能問題,以及在生產環境下應該如何解決,
1. 短連接風暴
當由于大量短連接造成資料庫性能低時,首先考慮一些無損安全的解決方案,如果是必須立刻提升一些資料庫性能,那么可以考慮下面的方案,
第一種方法:處理掉占著連接但空閑的執行緒
類似 MySQL wait_timeout 的邏輯,當檢測到執行緒空閑(sleep狀態)超過一定時間,就在服務端主動斷開與客戶端的連接,為后續新到來的連接騰出位置,
從資料庫端斷開連接的方法是有損的,因為應用端收到這個錯誤后,不會重新連接,而是用這個不能再用的句柄繼續重試查詢,這會導致從應用端看上去,“MySQL一直沒恢復”,
第二種方法:減少連接程序的損耗
一種減少損耗的方法是連接時不進行權限驗證,即以 –skip-grant-tables 的方式重啟 MySQL,這樣后續的連接將不需要再進行權限驗證,但是這樣顯然很不安全,所以 MySQL8.0 在開啟 –skip-grant-tables 模式后,只允許本地客戶端連接 MySQL,
2. 慢查詢問題
慢查詢問題主要分三種情況:
- 索引設計不好
- SQL陳述句沒寫好
- 資料庫選錯索引
第一種情況:索引設計不好
原文復制:
MySQL5.6 以后可以 Online DDL,即支持在線更新表結構,所以,如果上線后發現索引沒設計好,就可以在線 Alter Table,
比較理想的是能夠在備庫先執行,假設你現在的服務是一主一備,主庫A、備庫B,這個方案的大致流程是這樣的:
在備庫B上執行 set sql_log_bin=off,也就是不寫binlog,然后執行alter table 陳述句加上索引;
執行主備切換;
這時候主庫是B,備庫是A,在A上執行 set sql_log_bin=off,然后執行alter table 陳述句加上索引,
這是一個“古老”的DDL方案,平時在做變更的時候,你應該考慮類似 gh-ost 這樣的方案,更加穩妥,但是在需要緊急處理時,上面這個方案的效率是最高的,
第二種情況:SQL陳述句沒寫好
MySQL5.7 提供了 query_rewrite 插件實作 SQL 重寫的功能,安裝 query_rewrite 插件后,會多一個 query_rewrite 資料庫,然后可以該資料庫的 rewrite_rules 表中新增重寫規則,舉例:
mysql> insert into query_rewrite.rewrite_rules(pattern, replacement, pattern_database) values ("select * from t where id + 1 = ?", "select * from t where id = ? - 1", "db1");
call query_rewrite.flush_rewrite_rules();
第三種情況:資料庫選錯索引
在 SQL 陳述句上加上 force index 來強制選擇索引,同樣可以使用 query_rewrite 插件重寫陳述句來解決,
原文復制:
上面的三種可能情況,出現最多的是前兩種,即:索引沒設計好和陳述句沒寫好,而這兩種情況,恰恰是完全可以避免的,比如,通過下面這個程序,我們就可以預先發現問題,
(1)上線前,在測驗環境,把慢查詢日志(slow log)打開,并且把long_query_time設定成0,確保每個陳述句都會被記錄入慢查詢日志;
(2)在測驗表里插入模擬線上的資料,做一遍回歸測驗;
(3)觀察慢查詢日志里每類陳述句的輸出,特別留意Rows_examined欄位是否與預期一致,
參考
- [1] MySQL有哪些“飲鴆止渴”提高性能的方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/303784.html
標籤:MySQL
上一篇:Hive語法及其進階(一)
