MySQL 影響SQL查詢速度
查詢速度為什麼會慢
SQL請求處理步驟
- 客戶端傳送SQL請求給MySQL伺服器
- MySQL伺服器會在查詢快取中進行檢查,檢視是否可以在查詢快取中命中
- 服務端會對SQL進行解析、預處理再由優化器生成對應的執行計劃
- 根據執行計劃,呼叫儲存引擎中的API來查詢資料
- 將查詢的資料返回給客戶端,必要的時候進行快取過濾
查詢快取
如果查詢快取開關是開啟的會優先對快取中檢查:
這個檢查是對大小寫敏感的hash查詢實現:so,只能進行全值匹配查詢。
如果在快取中命中查詢結果,會進行角色的許可權認證,然後跳過後面的步驟把資料返回給客戶端。
1. 查詢的SQL要和快取中的完全一致,所以命中並不容易。
2. 如果快取中的資料是正確的,需要每次修改表的時候進行快取的維護。
3. 而且進行快取中查詢的同時會對錶加鎖,所以對讀寫頻繁的應用,查詢快取很可能降低查詢效率(不建議開啟查詢快取)
查詢快取相關引數
query_cache_type:
0代表關閉查詢快取OFF,1代表開啟ON,2(DEMAND)代表當sql語句中有SQL_CACHE關鍵詞時才快取。
例:select SQL_CACHE user_name from users where user_id = ‘100’;
query_cache_size:
表示查詢快取大小,也就是分配記憶體大小給查詢快取,分配大小為1024整數倍;設定為0表示不快取
query_cache_limit :
控制快取查詢結果的最大值
MySql 可以設定一個最大的快取值,當你查詢快取數結果資料超過這個值就不會
進行快取。預設為1M,也就是超過了1M查詢結果就不會快取。
在 query_cache_type 開啟的情況下,如果你不想使用快取,需要使用sql_no_cache關鍵字
例:select sql_no_cache id,name from tableName;
query_cache_wlock_invalidate:
如果一個表被加鎖是否允許直接從快取中讀取結果,預設為FALSE。
query_cache_min_res_unit:
查詢快取中存放的最小記憶體大小,預設4k;
SQL轉變為執行計劃
- 解析SQL
語法解析階段是通過關鍵字對mysql進行語法解析並生成一顆對應的解析樹
此階段,使用MySQL語法規則驗證和解析查詢:檢查語法是否使用的正確的關鍵字和關鍵字的位置是否正確 - 預處理
預處理階段進一步的驗證檢查解析樹是否合法
此階段檢查查詢中所涉及的表和資料列是否存在及名字或者別名是否有存在歧義 - 優化SQL執行計劃
查詢優化器生成查詢計劃
影響查詢計劃生成的因素
- 統計資訊不準確
- 執行計劃中的成本估算並不等於實際的執行計劃成本
mysql伺服器層並不知道哪些頁面在記憶體中,哪些頁面在磁碟中,哪些頁面順序讀,哪些頁面要隨機讀 - mysql所認為的最優可能和我們所認為的最優並不一致
mysql基於其成本模型選擇最優的執行計劃 - mysql不會考慮到其他的併發查詢
- 有時候也會基於一些固定的規則來生成執行計劃
- mysql不會考慮不受其控制的成本,如:儲存過程和使用者自定義的函式
MySQL可以優化的SQL型別
- mysql會重新定義標的關聯順序
- 將外連結轉換成內連線
- 使用等價變換原則
- 可以利用索引對count(),min(),max()進行優化。如最小值 btree索引第一個資料
- 將表示式轉化為一個常數
- 子查詢優化:把子查詢轉換成關係查詢
- 會提前終止查詢:如發現不成立的條件,如屬性設定為正數,查詢條件是負數
- 對in()進行優化,會對in中的資料進行排序,然後進行二分查詢
如何確定查詢各個階段所消耗的時間
profile
Profiling是從 mysql5.0.3版本以後才開放的。
啟動profile之後,所有查詢包括錯誤的語句都會記錄在內。
profile是一個session級別的配置,關閉會話或者set profiling=0 就關閉了。(如果將profiling_history_size引數設定為0,同樣具有關閉MySQL的profiling效果。)
show profiles
show profile for query N 查詢每個階段所消耗的時間
5.5之後使用performance_schma