學習筆記 mysql查詢優化器的侷限性

2021-07-31 14:16:38 字數 2767 閱讀 4071

本文屬於讀書筆記,大部分內容摘抄於《高效能mysql》,摘抄內容版權屬於原作者。

mysql的萬能「巢狀迴圈」並不是對每種查詢都是最優的。不過還好,mysql查詢優化器只對少部分查詢不適用,而且我們往往可以通過改寫查詢讓mysql高效的完成工作。而5.6以後會消除很多mysql原本的限制,讓更多的查詢能夠以盡可能高的效率完成。

關聯子查詢

mysql的子查詢實現的是很糟糕的。最糟糕的一類查詢時where條件中包含in()的子查詢語句。

union的限制

有時,mysql無法將限制條件從外層「下推」到內層,這使得原本能夠限制部分返回結果的條件無法應用到內層的查詢優化上。

如果希望union的各個子句能夠根據limit只取部分結果集,或者希望能夠先排好序再合併結果集的話,就需要在union的各個自劇中分別使用這些子句。

索引合併優化

在5.0和更新版本中,當where子句中包涵多個複雜條件的時候,mysql能夠訪問單個表的多個索引以合併和交叉過濾的方式來定位需要查詢的行。

等值傳遞

某些時候,等值傳遞會帶來一些意想不到的額外消耗。例如,有乙個非常大的in()列表,而mysql優化器發現存在where、on或者using的子句,將這個列表的值和另乙個列表的某個列關聯。

那麼優化器會將in()列表都複製應用到關聯的各個表中。通常因為各個表新增了過濾條件,優化器可以更高效地從儲存引擎過濾記錄。但是如果這個列表非常大,則會導致優化和執行都會變得很慢。

並行執行

mysql無法利用多核特性來並行執行查詢。很多其他的關係型資料庫能夠提供這個特性,但是mysql做不到。

雜湊關聯

到目前為止,mysql並不支援雜湊關聯——mysql的所有關聯都是巢狀迴圈關聯。不過可以通過建立乙個雜湊索引來曲線地實現雜湊關聯。

鬆散索引掃瞄

由於歷史原因,mysql並不支援鬆散索引掃瞄(相當於oracle中的跳躍索引掃瞄),也就無法按照不連續的方式掃瞄乙個索引。通常,mysql的索引掃瞄需要定義乙個起點和乙個重點,即使需要的資料只是這段索引中很少數的幾個,mysql仍需要掃瞄這段索引中的每個條目。

最大值和最小值優化

對於min()和max()查詢,mysql的優化做的並不好。有乙個很明顯的例子:

mysql

>

select min

(actor_id

)from sakila

.actor where first_name

='penelope'

因為在first_name欄位上沒有索引,因此mysql將會進行一次全表掃瞄。如果mysql能夠進行主鍵掃面,那麼理論上,當mysql讀到第乙個滿足條件的記錄的時候就是我們需要找的最小值了,因為主鍵是嚴格感召actor_id欄位的大小順序排序的。但是mysql這時只會做全表掃瞄。乙個曲線的優化方法是移除min(),然後使用limit來將查詢重寫如下:

mysql

>

select actor_id from sakila

.actor use index

(primary

)

->

where first_name

='penelope'

limit

1;

這個策略可以讓mysql掃瞄盡可能少的資料記錄。

在同乙個表上查詢和更新

mysql不容許對同一張彪同事進行查詢和更新。這其實並不是優化器的限制,如果清楚mysql是如何執行查詢的,就可以避免這種情況。下面是乙個無法執行的sql,雖然這是乙個符合標註的sql語句。這個sql語句嘗試將兩個表中相似的行的數量記錄到字段cnt中

mysql

>

update tb1 as outer_tb1

->

set cnt

=(

->

select count

(*)from tb1 as inner_tb1

->

where inner_tb1

.type

=outer_tb1

.type

->

);

可以通過生成表的形式繞過上面的限制,因為mysql只會把這個表當做乙個臨時表來處理。實際上,這執行了兩個查詢:乙個是子查詢中的select語句,另乙個是奪標關聯update,只是關聯表的乙個臨時表。子查詢會在update語句開啟表之前就完成,所以下面的查詢將會正常執行:

mysql

>

update tb1

->

inner join

(

->

select type

,count

(*)as cnt

-> from tb1

-> group by type

->

) as der using(type)

-> set tb1.cnt = der.cnt

MySQL學習筆記 查詢效能優化

查詢效能低下最根本的原因就是訪問的資料太多,大部分效能低下的查詢都可以通過減少訪問的資料量進行優化。一般有效的分析步驟如下 優化有問題的查詢時,目標應該是找到乙個更優的方法獲取實際需要的資料,而不是一定總是從mysql獲取一模一樣的結果集。優點 快取效率更高。許多應用程式可以方便地快取單錶查詢對應的...

MYSQL查詢優化器

1 優化器本質 計算io成本 減少io訪問次數 計算cpu成本 制定成本消耗最低的方案 2 優化的兩個階段 邏輯查詢計畫優化 邏輯表示式,算術運算子等 物理查詢計畫優化 mysql中的各級buffer cache 1 buffer cache用於訪問加速以記憶體空間換取效能 2 在幾乎所有需要磁碟i...

MySQL筆記(查詢優化)

查詢效能優化 基本原則 優化資料訪問 一些典型的錯誤包括 提取了超過需要的行 多表聯接時提取所有列或提取所有的列 select 可能會造成覆蓋索引這樣的優化手段失效 mysql中,最簡單的開銷指標包括 1.執行時間 2.檢查的行數 3.返回的行數 通過使用索引,在explain時可以減少處理的行數 ...