天天看點

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

一、SQL查詢優化(重要)

1.1 擷取有性能問題SQL的三種方式

  1. 通過使用者回報擷取存在性能問題的SQL;
  2. 通過慢查日志擷取存在性能問題的SQL;
  3. 實時擷取存在性能問題的SQL;

1.1.2 慢查日志分析工具

相關配置參數:

slow_query_log # 啟動停止記錄慢查日志,慢查詢日志預設是沒有開啟的可以在配置檔案中開啟(on)
slow_query_log_file # 指定慢查日志的存儲路徑及檔案,日志存儲和資料從存儲應該分開存儲

long_query_time # 指定記錄慢查詢日志SQL執行時間的閥值預設值為10秒通常,對于一個繁忙的系統來說,改為0.001秒(1毫秒)比較合适
log_queries_not_using_indexes #是否記錄未使用索引的SQL
           

常用工具:mysqldumpslow和pt-query-digest

pt-query-digest --explain h=127.0.0.1,u=root,p=p@ssWord  slow-mysql.log
           

1.1.3 實時擷取有性能問題的SQL(推薦)

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化
SELECT id,user,host,DB,command,time,state,info
FROM information_schema.processlist
WHERE TIME>=60
           

查詢目前伺服器執行超過60s的SQL,可以通過腳本周期性的來執行這條SQL,就能查出有問題的SQL。

1.2 SQL的解析預處理及生成執行計劃(重要)

1.2.1 查詢過程描述(重點!!!)

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

通過上圖可以清晰的了解到MySql查詢執行的大緻過程:

  1. 發送SQL語句。
  2. 查詢緩存,如果命中緩存直接傳回結果。
  3. SQL解析,預處理,再由優化器生成對應的查詢執行計劃。
  4. 執行查詢,調用存儲引擎API擷取資料。
  5. 傳回結果。

1.2.2 查詢緩存對性能的影響(建議關閉緩存)

第一階段:

相關配置參數:

query_cache_type # 設定查詢緩存是否可用
query_cache_size # 設定查詢緩存的記憶體大小
query_cache_limit # 設定查詢緩存可用的存儲最大值(加上sql_no_cache可以提高效率)
query_cache_wlock_invalidate # 設定資料表被鎖後是否傳回緩存中的資料
query_cache_min_res_unit # 設定查詢緩存配置設定的記憶體塊的最小單
           
緩存查找是利用對大小寫敏感的哈希查找來實作的,Hash查找隻能進行全值查找(sql完全一緻),如果緩存命中,檢查使用者權限,如果權限允許,直接傳回,查詢不被解析,也不會生成查詢計劃。

在一個讀寫比較頻繁的系統中,建議關閉緩存,因為緩存更新會加鎖。将query_cache_type設定為off,query_cache_size設定為0。

1.2.3  第二階段:MySQL依照執行計劃和存儲引擎進行互動

這個階段包括了多個子過程:

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

一條查詢可以有多種查詢方式,查詢優化器會對每一種查詢方式的(存儲引擎)統計資訊進行比較,找到成本最低的查詢方式,這也就是索引不能太多的原因。

1.3 會造成MySQL生成錯誤的執行計劃的原因

    1、統計資訊不準确

    2、成本估算與實際的執行計劃成本不同

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

   3、給出的最優執行計劃與估計的不同

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

    4、MySQL不考慮并發查詢

    5、會基于固定規則生成執行計劃

    6、MySQL不考慮不受其控制的成本,如存儲過程,使用者自定義函數

1.4 MySQL優化器可優化的SQL類型

查詢優化器:對查詢進行優化并查詢mysql認為的成本最低的執行計劃。為了生成最優的執行計劃,查詢優化器會對一些查詢進行改寫

  可以優化的sql類型

  1、重新定義表的關聯順序;

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

  2、将外連接配接轉換為内連接配接;

  3、使用等價變換規則;

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

  4、優化count(),min(),max();

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

  5、将一個表達式轉換為常數;

  6、子查詢優化;

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

  7、提前終止查詢,如發現一個不成立條件(如where id = -1),立即傳回一個空結果;

  8、對in()條件進行優化;

1.5 查詢處理各個階段所需要的時間

1.5.1 使用profile(目前已經不推薦使用了)

set profiling = 1; #啟動profile,這是一個session級的配制執行查詢

show profiles; # 查詢每一個查詢所消耗的總時間的資訊

show profiles for query N; # 查詢的每個階段所消耗的時間
           

1.5.2 performance_schema是5.5引入的一個性能分析引擎(5.5版本時期開銷比較大)

啟動監控和曆史記錄表:use performance_schema

update setup_instruments set enabled='YES',TIME = 'YES' WHERE NAME LIKE 'stage%';

update set_consumbers set enabled='YES',TIME = 'YES' WHERE NAME LIKE 'event%';
           
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

1.6 特定SQL的查詢優化

1.6.1 大表的資料修改

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

1.6.2 大表的結構修改

對表中的列的字段類型進行修改

改變字段的寬度時還是會鎖表

無法解決主從資料庫延遲的問題

  1. 利用主從複制,先對從伺服器進入修改,然後主從切換
  2. (推薦)
添加一個新表(修改後的結構),老表資料導入新表,老表建立觸發器,修改資料同步到新表, 老表加一個排它鎖(重命名), 新表重命名, 删除老表。
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

修改語句這個樣子:

alter table sbtest4 modify c varchar(150) not null default ''
           

利用工具修改:

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

1.6.3 優化not in 和 <> 查詢

  子查詢改寫為關聯查詢:

SELECT customer_id,first_name,last_name,email 
FROM customer
WHERE customer_id
NOT IN (SELECT customer_id FROM payment) 
           

改寫後:

SELECT a.customer_id,a.first_name,a.last_name,a.email 
FROM customer a
LEFT JOIN payment b ON a.customer_id = b.customer_id
WHERE b.customer_id IS NULL
           

二、分庫分表

2.1 分庫分表的幾種方式

分擔讀負載 可通過 一主多從,更新硬體來解決。

2.1.1 把一個執行個體中的多個資料庫拆分到不同執行個體(叢集)

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

拆分簡單,不允許跨庫。但并不能減少寫負載。

2.1.2 把一個庫中的表分離到不同的資料庫中

MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

該方式隻能在一定時間内減少寫壓力。

以上兩種方式隻能暫時解決讀寫性能問題。

2.1.3  資料庫分片

對一個庫中的相關表進行水準拆分到不同執行個體的資料庫中
MySQL:資料庫結構優化、高可用架構設計、資料庫索引優化

2.1.3.1 如何選擇分區鍵

  1. 分區鍵要能盡可能避免跨分區查詢的發生
  2. 分區鍵要盡可能使各個分區中的資料平均

2.1.3.2 分片中如何生成全局唯一ID