sql優化的通常策略

sql 優化的通常策略:索引優化,sql改寫,參數優化,優化器html

索引優化

select * from vvshop_order.vv_order where receive_phone='151011324532'; 爲例分析java

explain select * from vv_order where order_no=23;複製代碼

結果:mysql

202006011431Meh70c52

分析:能夠看到該sql掃描全表 30 多萬記錄,能夠經過添加索引優化sql

alter table vv_order add index orderno_idx(order_no);複製代碼

202006011432J7bRPa14

注意點數據庫

  • 當傳入的數據類型和庫表數據類型不一致時,索引會失效
  • 不要爲每一個查詢字段創建單獨的索引,應該根據實際須要創建單列索引或者組合索引
  • 經過explain+extended 檢查sql的執行計劃,是否使用索引,是否發生隱式轉換
  • 避免在查詢條件中使用函數

sql 改寫

分頁優化

原sql select * from buyer where sellerid=100 limit 100000,5000, limit M, N 寫法中,M越大,性能越差,能夠改寫爲緩存

select t1.* from buyer t1,
(select id from buyer sellerid=100 limit 100000,5000) t2
where t1.id=t2.id;複製代碼
子查詢優化
  1. 查詢數量較多時,in改成exist,或者優化爲以下的形式性能優化

    SELECT first_name
    FROM employees emp,
    (SELECT emp_no FROM salaries_2000 WHERE salary = 5000) sal
    WHERE emp.emp_no = sal.emp_no;複製代碼
  2. 避免查詢返回全部字段,只返回須要的字段數據數據結構

不使用 select *
or 改寫爲 in

or的效率事n,in的效率是log(n),控制in數量在200之內多線程

不使用函數和觸發器,經過應用程序實現
少用join,保證字段類型一直再join或比較
連續數值 使用 between

參數優化

優化器

其餘

影響in是否生效的因素
  1. eq_range_index_dive_limit 參數併發

    202006011432iMRPw431

    默認爲10

    eq_range_index_dive_limit = 0 只能使用index dive

    0 < eq_range_index_dive_limit <= N 使用index statistics

    eq_range_index_dive_limit > N 只能使用index dive

字段
  1. 根據實際使用狀況設置字段類型
  2. 單表不要有太多字段,建議20之內
  3. 避免使用null字段,優化較難且額外佔用索引空間
  4. 用整型來存IP

系統參數調優

基準測試工具
  1. sysbench:模塊化,跨平臺以及多線程的性能測試工具
  2. iibench-mysql:基於java的插入性能測試工具
  3. tpcc-mysql:Percona 開發的TPC-C 測試工具
這裏介紹一些比較重要的參數:

back_log

backlog值指出在MySQL暫時中止回答新請求以前的短期內多少個請求能夠被存在堆棧中。也就是說,若是MySql的鏈接數據達到maxconnections時,新來的請求將會被存在堆棧中,以等待某一鏈接釋放資源,該堆棧的數量即backlog,若是等待鏈接的數量超過backlog,將不被授予鏈接資源。能夠從默認的50升至500

wait_timeout

數據庫鏈接閒置時間,閒置鏈接會佔用內存資源。能夠從默認的8小時減到半小時

maxuserconnection

最大鏈接數,默認爲0無上限,最好設一個合理上限thread_concurrency:併發線程數,設爲CPU核數的兩倍

skipnameresolve

禁止對外部鏈接進行DNS解析,消除DNS解析時間,但須要全部遠程主機用IP訪問

keybuffersize

索引塊的緩存大小,增長會提高索引處理速度,對MyISAM表性能影響最大。對於內存4G左右,可設爲256M或384M,經過查詢show status like'keyread%',保證keyreads / keyreadrequests在0.1%如下最好

innodbbufferpool_size

緩存數據塊和索引塊,對InnoDB表性能影響最大。經過查詢show status like 'Innodbbufferpoolread%',保證 (Innodbbufferpoolreadrequests – Innodbbufferpoolreads)/ Innodbbufferpoolreadrequests 越高越好

innodbadditionalmempoolsize

InnoDB存儲引擎用來存放數據字典信息以及一些內部數據結構的內存空間大小,當數據庫對象很是多的時候,適當調整該參數的大小以確保全部數據都能存放在內存中提升訪問效率,當太小的時候,MySQL會記錄Warning信息到數據庫的錯誤日誌中,這時就須要該調整這個參數大小

innodblogbuffer_size

InnoDB存儲引擎的事務日誌所使用的緩衝區,通常來講不建議超過32MB

querycachesize

緩存MySQL中的ResultSet,也就是一條SQL語句執行的結果集,因此僅僅只能針對select語句。當某個表的數據有任何任何變化,都會致使全部引用了該表的select語句在Query Cache中的緩存數據失效。因此,當咱們的數據變化很是頻繁的狀況下,使用Query Cache可能會得不償失。根據命中率(Qcachehits/(Qcachehits+Qcache_inserts)*100))進行調整,通常不建議太大,256MB可能已經差很少了,大型的配置型靜態數據可適當調大.

能夠經過命令show status like 'Qcache_%'查看目前系統Query catch使用大小

readbuffersize

MySql讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql會爲它分配一段內存緩衝區。若是對錶的順序掃描請求很是頻繁,能夠經過增長該變量值以及內存緩衝區大小提升其性能

sortbuffersize

MySql執行排序使用的緩衝大小。若是想要增長ORDER BY的速度,首先看是否可讓MySQL使用索引而不是額外的排序階段。若是不能,能夠嘗試增長sortbuffersize變量的大小

readrndbuffer_size

MySql的隨機讀緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySql會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySql會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開銷過大。

record_buffer

每一個進行一個順序掃描的線程爲其掃描的每張表分配這個大小的一個緩衝區。若是你作不少順序掃描,可能想要增長該值

threadcachesize

保存當前沒有與鏈接關聯可是準備爲後面新的鏈接服務的線程,能夠快速響應鏈接的線程請求而無需建立新的

table_cache

相似於threadcachesize,但用來緩存表文件,對InnoDB效果不大,主要用於MyISAM

References

阿里雲慢SQL優化挑戰大賽分析

SQL優化器原理 - 查詢優化器綜述

MYSQL查詢SQL語句性能優化方法

MySQL--eq_range_index_dive_limit參數學習

MySQL SQL優化之in與range查詢【轉】

本文由 歧途老農 創做,採用 CC BY 4.0 CN 協議 進行許可。 可自由轉載、引用,但需署名做者且註明文章出處。

相關文章
相關標籤/搜索