Mysql 階段調優

效率基礎

  • 通常應用讀寫比例大概在10:1
  • IO成本磁盤大概是內存的十萬倍
  • 高負載讀應用支持千萬量級數據,高負載寫應用支持百萬量級數據
  • 索引採用了高可用多路搜索樹構(B+Tree,非葉子節點不存儲真實的數據,只存儲指引搜索方向的數據項)
  • 索引查詢遵循最左前綴匹配原則

數據庫階段調優

1. 數據設計階段

  • 表引擎選擇
    高頻插入、更新的表使用InnoDB引擎
    高頻讀取的表使用MyISAM引擎mysql

  • 字段設計
    字段名:所有小寫、下劃線鏈接
    儘量小的字段類型 ,儘量unsigned
    NOT NULL(避免NULL比較)
    字段約束默認值(減小插入次數)
    ENUM代替String類型(ENUM被當作數值類型處理,這條較少運用)
    小數使用decimal類型,長度不夠則拆分整數和小數分別存儲
    文本字段:長度接近則char,不一樣則varchar,超過5000則text並建議單獨表(不然影響其餘數據索引效率)sql

  • 合理利用索引
    索引創建原則
    索引名:主鍵pk_前綴,惟一uk_前綴,普通idx_前綴
    UNIQ索引優先於INDEX索引 選擇區分度高的whereorder列建立索引(區分度小於0.3查詢計劃會忽略索引,惟一鍵的區分度是1)
    儘可能的擴展複合索引,不要新建索引(區分度高的字段放最左邊)
    範圍查詢><betweenlike列放在複合索引構建字段集的的末尾(複合索引查詢向右匹配直至範圍查詢列而止)
    索引使用原則
    where的列順序不作要求,查詢計劃會自動調整以匹配複合索引列順序
    批量數據插入前應先刪除索引,結束後再重建
    排序字段要利用索引, 只能結合過濾字段作複合索引數據庫

  • 冗餘字段
    適當添加的字段冗餘能減小多表查詢,提升查詢效率
    空間換時間
    冗餘字段不該該是超長字段、頻繁更新字段(不然數據一致性的處理成本過高)緩存

  • 簡化權限設置
    sql查詢前的權限判斷有較高的時間損耗swoole

2. 查詢階段

  • 小表驅動大表查詢
    能夠考慮在FROM以後利用子查詢,儘量的在最終查詢前縮減表規模 如:select x.* from (select * from a where id < 100) as x left join b on b.extid= x.id架構

  • 避免在FROM以前使用子查詢
    應改成JOIN代替,不然主表每條記錄都會進行一次子查詢產生笛卡爾積問題,佔用大量內存資源
    如:select a.*, (select x from y where extid = a.id) as b from a併發

  • 字段比較使用相同數據類型
    避免查詢值和字段原始類型比較時發生類型轉換,類型轉換可能還會致使索引無效,同時引入巨大的轉換開銷運維

  • join查詢
    join字段必須類型一致,且索引性能

  • like查詢
    禁止左模糊或者全模糊(索引文件具備B-Tree的最左前綴匹配特性,若是左邊的值未肯定,那麼沒法使用此索引)
    考慮使用檢索引擎實現優化

3. SQL調優階段

  • 慢查日誌
    慢查日誌能記錄應用運行期間超出時間閾值的慢查詢

  • Show Profile分析
    sql語句性能分析,查找效率瓶頸

  • Explain分析查詢計劃

**使用**
    - `explain 查詢語句`
    - 查詢序列號越大, 優先級越高,越先被執行  
    
    **幾個重要字段**
    - select 當前的查詢類型:簡單查詢、聯合查詢等
    - possible_keys 當前查詢的可選索引
    - key 當前查詢實際使用索引

    **優化目標(通常經過索引來達成)**
    - 優化訪問類型type(優到次順序爲:·system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL·)
    - 顯示覆蓋索引 using index
    - 減小掃面行數rows
    - 避免Using filesort

4. 鏈接優化階段

  • 鏈接參數調優
    最大併發鏈接數max_connectionsmax_user_connections
    最大請求暫存堆棧數back_log

  • mysql線程緩存池複用鏈接
    配置thread_cache_size參數(每G內存能夠配備8個鏈接線程,但要小於數據庫鏈接數限制)

  • mysql長鏈接在超時內複用鏈接

  • 中間件維護鏈接池複用鏈接
    可經過swoole來實現鏈接池

5. 架構優化階段

  • 設計冗餘中間表
    將高耗時的子查詢結果集裝載到一張冗餘中間表中

  • 複製特性作主從
    讀寫分離
    自動故障切換避免單點問題

  • 垂直分庫分表
    大表拆小表,不經常使用字段移植到新建表中,減少單表規模
    爲了後期的水平拓展優化,這裏要求禁用 join查詢、子查詢等

  • 水平拓展策略 - 分庫分表
    單表超過500萬行或2G才建議分庫分表
    該措施會在後期形成較多的開發、運維困難,不到萬不得已不建議實施
    利用 MOD、HASH、月分表 等shard方案減少單表規模

  • 應用/數據庫之間架設緩存層 儘可能避免請求直接穿透到數據庫

6. 平常維護階段

  • OPTIMIZE語句
    空間回收、數據重排、更新統計等工做

  • 設備升級 使用RAID、SSD等高速IO設備 切換到雲數據庫


其中,水平分庫分表、讀寫分離、鏈接池等措施通常都要藉助於數據庫中間件來實施。

相關文章
相關標籤/搜索