MySQL複雜where條件分析

2022-01-10 07:05:49 字數 2156 閱讀 7376

在《mysql 常見語句加鎖分析》一文中,我們詳細講解了 sql 語句的加鎖原理並具體分析了大部分的簡單 sql 語句,但是實際業務場景中 sql 語句往往及其複雜,包含多個條件,此時就需要具體分析sql 使用到的索引,並了解 where 條件的判斷邏輯。

我們可以直接使用 explain 或者 optimizer_trace 來分析 sql 語句執行使用了哪些索引,具體使用可以看本系列文章的前兩篇文章。但是,今天我們講一下具體 where 語句的條件的拆分和使用,即複雜 where 條件是如何生效的。

用何登成大神的原話,就是

給定一條sql,where條件中的每個子條件,在sql執行的過程中有分別起著什麼樣的作用?

我們使用下面這張 book 表作為例項,其中 id 為主鍵,isbn(書號)為二級唯一索引,author(作者)為二級非唯一索引,score(評分)無索引。

基於上述表,我們具體分析一下如下擁有複雜 where 條件的 sql 語句。

mysql> update book set score = 9.0 where author = 'tom' and isbn > 'n0004' and isbn < 'n0007';
上述 sql 語句的 where 條件使用了兩個索引,分別是二級唯一索引 isbn 和二級非唯一索引 author。mysql 會根據索引選擇性等指標選擇其中乙個索引來使用,而另外乙個沒有被使用的 where 條件就被當做普通的過濾條件,一般稱被用到的索引稱為index key,而作為普通過濾的條件則被稱為table filter。比如上面這條sql 使用 isbn索引來查詢,則 isbn 就是 index key,而 author = 'tom' 這個條件就是 table filter。

所以,該 sql 執行的過程就是依次將 index key 範圍內的索引記錄讀取,然後回表讀取完整資料記錄,然後返回給mysql的服務層按照 table filter 進行過濾。 至於加鎖,如下圖所示則需要將涉及的 index key 對應的索引記錄都進行加鎖。

但是當使用的索引是復合索引時,則還可能出現 index filter,利用它可以減少回表次數和返回給 mysql 服務層的記錄的數量,降低儲存引擎和服務層的互動開銷,提高 sql 的執行效率。

假設我們在 book 表的 isbn 和 author 列上建立了聯合索引,並且上述 sql 執行時選擇了該復合索引。

對於這個場景,mysql 依然使用 isbn > 'n0004' and isbn < 'n0007' 條件來確定 sql 查詢在索引中的連續位置,但是 author = 'tom' 可以用來直接過濾索引,即該條件可以使用復合索引來直接過濾條件,不需要讀取所有資料後由mysql 服務層根據 table filter 來過濾。這就是傳說中的 icp(index condition pushdown,索引下推)技術,使用 index filter 過濾不滿足條件的記錄,無需加鎖

根據 index key 判斷查詢返回和根據 index filter 進行初步過濾後,儲存引擎將剩下的資料記錄返回給服務層,再由服務層根據 table filter 進行過濾。

mysql 5.6 推出的 icp 技術其實就是 index filter 技術,只不過是因為 mysql 分為服務層和儲存引擎層,而 index filter 將原本服務層做的過濾操作「下推」到儲存引擎層處理。將原來的在服務層進行的table filter中可以進行index filter的部分,在引擎層面使用 index filter 進行處理,不再需要回表進行 table filter。

這樣做的好處就是減少了加鎖的記錄數,減少了回表查詢的數量,提高了 sql 的執行效率。

個人部落格,歡迎來玩

mysql匯出錶帶where條件

引數介紹 c 完整的insert語句,包含欄位名的insert t 不要寫 建立資訊 set gtid purged mysql 5.6 引入了 gtid 特性 auto 預設值 對於啟用 gtid 伺服器,會輸出 set global.gtid purged 語句 對於沒有啟動或者不支援 gtid...

MySQL之where條件查詢

單錶查詢是mysql查詢中的一種常見的查詢方式,而where語句塊則在單錶查詢語句中起到指定查詢過濾條件的功能。語法為 select 字段列表 表示式 from table name where 條件 order by 字段列表 說明 相當於按照表中字段順序羅列表中的所有字段 字段列表 當查詢結果只...

where 條件為空時不走where條件

mysql 若想當where 條件為空時不走where條件,where可以整個為空,但裡面的如where is status sta tus 的 status 的 status 的status不能為空,不然會查詢出status為空的資料,記錄一下。where sta demandstatus if ...