《高效能MySQL》第6章 查詢效能優化

2021-10-20 21:12:29 字數 2294 閱讀 2132

6.2 慢查詢基礎:優化資料訪問

6.2.1 是否向資料庫請求了不需要的資料

有些查詢會請求超過實際需要的資料,然後這些多餘的資料會被應用程式丟棄。這會給mysql伺服器帶來額外的負擔,並增加網路開銷,另外也會消耗應用伺服器的cpu和記憶體資源。

6.2.2 mysql是否在掃瞄額外的記錄
6.3 重構查詢的方式

6.3.1 乙個複雜查詢還是多個簡單查詢

設計查詢的時候乙個需要考慮的重要問題是,是否需要將乙個複雜的查詢分成多個簡單的查詢。

6.4 查詢執行的基礎

6.4.1 mysql客戶端/伺服器通訊協議

mysql客戶端和伺服器之間的通訊協議是「半雙工」的,這意味著,在任何乙個時刻,要麼是由伺服器向客戶端傳送資料,要麼是由客戶端向伺服器傳送資料,這兩個動作不能同時發生。

6.4.2 查詢快取
在解析乙個查詢語句之前,如果查詢快取是開啟的,那麼mysql會優先檢查這個查詢是否命中查詢快取中的資料。這個檢查是通過乙個對大小寫敏感的雜湊查詢實現的。

6.4.3 查詢優化處理
6.5 mysql查詢優化器的侷限性

6.5.1 關聯子查詢

mysql的子查詢實現得非常糟糕。最糟糕的一類查詢是where 條件

中包含in() 的子查詢語句。mysql會將相關的外層表壓到子查詢中,它認為這樣可以更高效率地查詢到資料行。

6.5.2 union的限制
如果希望union 的各個子句能夠根據limit 只取部分結果集,或者

希望能夠先排好序再合併結果集的話,就需要在union 的各個子句中分

別使用這些子句。

這條查詢將會把actor 中的200條記錄和customer 表中的599條記錄存放在乙個臨時表中,然後再從臨時表中取出前20條。可以通過在union 的兩個子查詢中分別加上乙個limit 20 來減少臨時表中的資料:

6.5.3 索引合併優化
在前面的章節已經討論過,在5.0和更新的版本中,當where 子句中包含多個複雜條件的時候,mysql能夠訪問單個表的多個索引以合併和交叉過濾的方式來定位需要查詢的行。

6.7 優化特定型別的查詢

6.7.1 優化count()查詢

當我們使用count() 的時候,這種情況下萬用字元並不會像我們猜想的那樣擴充套件成所有的列,實際上,它會忽略所有的列而直接統計所有的行數。

6.7.2 優化關聯查詢

6.7.3 優化子查詢

關於子查詢優化我們給出的最重要的優化建議就是盡可能使用關聯查詢代替,至少當前的mysql版本需要這樣。

6.7.4 優化group by 和distinct

6.7.5 優化limit分頁

乙個非常常見又令人頭疼的問題就是,在偏移量非常大的時候 (27),例如可能是limit 1000,20 這樣的查詢,這時mysql需要查詢10 020條記錄然後只返回最後20條,前面10000條記錄都將被拋棄,這樣的代價非常高

優化此類分頁查詢的乙個最簡單的辦法就是盡可能地使用索引覆蓋掃瞄,而不是查詢所有的列。然後根據需要做一次關聯操作再返回所需的列

這裡的「延遲關聯」將大大提公升查詢效率,它讓mysql掃瞄盡可能少的頁面,獲取需要訪問的記錄後再根據關聯列回原表查詢需要的所有列

有時候也可以將limit 查詢轉換為已知位置的查詢,讓mysql通過範圍掃瞄獲得到對應的結果。例如,如果在乙個位置列上有索引,並且預先計算出了邊界值,上面的查詢就可以改寫為:

《高效能MySQL》第6章查詢效能優化(4)

mysql通過建立並填充臨時表的方式來執行union,因此很多優化無法在union查詢中很好應用。所以需要手動將where limit order by等語句下推到union子查詢中。如果不是需要對結果去重,請使用union all。即使有all,mysql也會將結果先存於臨時表中,再讀出,這很多時...

《高效能MySQL》之MySQL查詢效能優化

響應時間過長。如果把查詢看做是乙個任務,那麼它由一系列子任務組成,每個子任務都會消耗一定的時間。如果要優化查詢,實際上優化其子任務,要麼消除其中一些子任務,要麼減少子任務的執行次數,要麼讓子任務執行得更快。查詢的生命週期 客戶端 伺服器 伺服器上解析 生成執行計畫 執行 返回結果給客戶端。其中 執行...

高效能mysql 樹 高效能mysql精要

1 explain 中 extra using index 表示覆蓋索引,sql優化中最好能使用覆蓋索引,否則 二級索引 需要回表查詢。所謂覆蓋索引,是指要查詢的列正好是索引,而條件也是這個索引之一 2 where 語句中 條件等於主鍵的 在核心索引層完成,條件等於非索引的,在服務層完成 3 讀索引...