查詢優化 索引優化 庫表結構優化
優化查詢嗎,實際上是優化其子任務。
優化查詢:
1。消除子任務
2。減少子任務執行次數
3。讓子任務執行的更快
查詢效能低下最基本的原因是訪問的資料太多。
(1)返回的結果
limit,避免返回不需要的資料(而不是返回全部結果集)
select * ?是否需要返回全部列?
(2)掃瞄的記錄
衡量查詢開銷的三個指標:響應時間、掃瞄的行數、返回的行數
響應時間=服務時間+排隊時間(io/所等待等等)
掃瞄的行數,在一定程度上說明找到需要的資料效率高不高。
掃瞄的行數和訪問型別
explain 裡的type就是訪問型別,如全表掃,索引掃,範圍掃,唯一索引查詢,常數引用等
索引讓mysql以高效、掃瞄行數最少的方式返回需要找的記錄
explain裡的extra:using index 索引覆蓋掃瞄,無需回表
using where 從資料表中返回記錄,用where條件過濾。
mysql客戶端/伺服器通訊協議是半雙工的
max_allowed_packet:客戶端往伺服器傳送查詢語句(只使用乙個資料報,而不是多個資料報),當查詢語句很長的時候,這個引數很重要,否則伺服器會拒絕接受更多的數 據並丟擲錯誤。
mysql通常需要等所有的資料都已經傳送給客戶端才能釋放這條查詢所占用的資源
種種原因可以看出,返回的結果集不要太大
查詢狀態:show full proccesslist中的command列顯示資訊。
查詢快取,先通過hash值進行比較,通過的話再驗證使用者許可權,因為被快取的表的許可權已經存放在當前快取中了。
語法解析器解析語法,預處理器驗證許可權。
查詢優化器將語法樹轉化成執行計畫。
mysql使用基於成本的優化器
mysql依賴儲存引擎提供的統計資訊來評估成本。
mysql優化器在評估成本的時候並不考慮任何層面的快取,它假設讀取任何資料都需要一次磁碟io。(感覺評估的很不準確啊)
計算代價時,mysql並不知道那些頁面在記憶體中,那些頁面在磁碟上。
靜態優化,動態優化。
靜態優化只需要做一次(不依賴於特別的值,即使使用不同的引數執行查詢也不會變化。) 編譯時優化
動態優化則在每次查詢的時候都重新評估(與引數取值,查詢上下文等都有關係。)。執行時優化
當進行in()查詢操作時,mysql會將in列表中的值排序,然後查詢。
伺服器層有優化器,但是沒有統計資訊。統計資訊由儲存引擎層實現。
mysql查詢優化器在生成執行計畫的時候需要向儲存引擎獲取相應的統計資訊。
mysql對任何關聯都執行巢狀迴圈關聯操作。
關聯查詢優化
straight_join 關鍵字讓mysql按照你認為的關聯順序執行
排序優化
不能使用索引進行排序時,統稱為檔案排序(filesort),即使完全是記憶體排序不需要任何磁碟檔案也是如此。
排序緩衝區不足時,使用磁碟,分塊排序。
兩次傳輸排序 :讀取行指標和需要排序的字段,對讀取的字段進行排序,然後根據排序好的字段和指標回表,讀取所需的資料行。
缺點是:需要進行兩次資料傳輸,第二次讀取的時候由於按照排序後的順序讀取,會產生大量隨機io。
優點是:在排序的時候儲存盡可能少的資料,讓排序緩衝區中容納盡可能多的行數進行排序。
單次傳輸排序 :先讀取查詢所需要的所有列(即select 語句中from之前的列表),然後根據給定的列進行排序。最後直接返回排序結果。
優點是 :不需要再從資料表中讀取,對於io密集型操作效率高了很多。相比兩次傳輸,只需要一次順序io,不需要隨機io。
缺點是 :需要返回的列非常多,非常大,會額外占用很多空間,但這些列隊排序操作本身來說沒有任何作用。因為單條排序記錄很大,可能會有更多排休愛需要合併。
max_length_for_sort_data :當查詢需要的所有列的總長度不超過這個值時,使用單次傳輸排序。
在關聯查詢的時候如果需要排序,mysql會分兩種情況來處理 :
1. using filesort的情況
如果order by子句中的所有列都來自關聯的第乙個表,那麼mysql會在關聯處理第乙個表的時候進行檔案排序。
這樣的話,在mysql的explain結果中可以看到extra欄位會有 using filesort。
2.using temporary;usingfilesort的情況
除了上面第一種情況之外,mysql都會先將關聯的結果存放到乙個臨時表中,然後再所有的關聯都結束後,再進行檔案排序。
這樣的話,在mysql的explain結果中國可以看到extra欄位會有 using temporary;using filesort。
high_priority 和low_priority 這兩個提示只對錶鎖的儲存引擎有效。
delayed 對insert和replace有效,資料先插入到緩衝區中然後立即返回給客戶端,然後等待表空閒時落盤。
straight_join 放在select 關鍵字之後,讓表按照出現的順序關聯
放在任何兩個關聯變中間,固定其前後兩個表的關聯順序。
sql_small_result 和 sql_big_result 只對select有效,告訴group by或者distinct如何使用臨時表及排序。是否會用到磁碟排序。
sql_buffer_result 將結果集快取到臨時表,盡快釋放表鎖,而不是將結果集傳輸到客戶端之後才釋放表鎖。減少表鎖的時間。代價是消耗服務端更多的記憶體。
sql_cache 和 sql_no_cache 是否將查詢結果快取到結果集快取中。
use_index ignore_index force_index
optmizer_search_depth 當連線的表比較多,mysql會嘗試各種連線方式以選取最優的執行計畫,這會耗費很多資源和時間,為了防止mysql嘗試太多執行計畫,設定此引數,窮舉執行計畫是有個限度。可以調整。
優化特定型別的查詢:
表關聯時,如果group by 或者order by中的表示式只涉及一張表上的列,可以用索引優化。否則不行。
子查詢盡量用關聯查詢優化,但也並非絕對。
group by 和 distinct 都可以用索引來優化,這是最有效的。否則只能用臨時表或檔案排序,可以使用sql_big_result或者sql_small_result提示。
用查詢表的標識列分組的效率比較高。
如果沒有通過order by字句顯示的指定拍序列,當查詢使用group by子句的時候,結果集會自動按照分組的字段排序。如果不關心結果集的順序,而這種預設排序又導致了需要檔案排序,可以使用order by null,讓mysql不再進行檔案排序。
優化limit分頁大偏移量的時候,如10000,20,最好用索引覆蓋掃瞄,而不是查詢所有的列。然後根據需要做一次關聯操作再返回所需的列。對於偏移量非常大的時候,這樣的操作效率提公升會非常大。
mysql總是通過建立並填充臨時表的方式來執行union查詢。
隊列表: 盡量使用update代替先select for update再update的方法,因為事務提交的速度快,持有鎖的時間就越短,大大減少競爭和加速序列執行效率。
mysql第六章 第六章 mysql日誌
第六章 mysql日誌 一 錯誤日誌 錯誤日誌的預設存放路徑是 mysql 存放資料的地方 hostname.err 1.修改錯誤日誌存放路徑 mysqld log error data mysql mysql.log 2.檢視配置命令 show variables like log error 3...
《高效能mysql》第六章讀書筆記
一 慢查詢優化語句 低效查詢的分析步驟 1.確認程式是否存在檢索大量超過需要的資料。2.確認伺服器層是否在分析大量的超出需要的資料行。下面詳細描述一下這兩方面 1.1 是否查詢了大量不必要的資料 1.查詢不需要的資料 2.多表關聯時候返回全部列 3.總是取出全部列 在大部分場景不建議如此,會耗費大量...
高效能MySQL 第六章查詢效能優化 查詢優化
查詢的生命週期下一步 將乙個sql轉換成乙個執行計畫,mysql再依照這個執行計畫和儲存引擎進行互動 解析sql 預處理 優化sql執行計畫 通過關鍵字將sql語句進行解析 解析器將使用mysql語法規範驗證解析查詢,生成解析樹,預處理器據規則檢查解析樹是否合法 優化器將語法樹從眾多執行方式中找到b...