最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL?WHERE語句用法小結

 更新時間:2024年01月10日 10:05:26   作者:重慶穿山甲  
給定一條SQL,如何提取其中的where條件,where條件中的每個子條件,在SQL執(zhí)行的過程中有分別起著什么樣的作用,本文就來介紹一下MySQL?WHERE?條件語句用法小結,感興趣的可以了解一下

問題描述

一條SQL,在數(shù)據(jù)庫中是如何執(zhí)行的呢?相信很多人都會對這個問題比較感興趣。當然,要完整描述一條SQL在數(shù)據(jù)庫中的生命周期,這是一個非常巨大的問題,涵蓋了SQL的詞法解析、語法解析、權限檢查、查詢優(yōu)化、SQL執(zhí)行等一系列的步驟,簡短的篇幅是絕對無能為力的。因此,本文挑選了其中的部分內(nèi)容,也是我一直都想寫的一個內(nèi)容,做重點介紹:

給定一條SQL,如何提取其中的where條件?where條件中的每個子條件,在SQL執(zhí)行的過程中有分別起著什么樣的作用?

通過本文的介紹,希望讀者能夠更好地理解查詢條件對于SQL語句的影響;撰寫出更為優(yōu)質的SQL語句;更好地理解一些術語,例如:MySQL 5.6中一個重要的優(yōu)化——Index Condition Pushdown,究竟push down了什么?

本文接下來的內(nèi)容,安排如下:

  • 簡單介紹關系型數(shù)據(jù)庫中數(shù)據(jù)的組織形式
  • 給定一條SQL,如何提取其中的where條件
  • 最后做一個小的總結

關系型數(shù)據(jù)庫中的數(shù)據(jù)組織

關系型數(shù)據(jù)庫中,數(shù)據(jù)組織涉及到兩個最基本的結構:表與索引。表中存儲的是完整記錄,一般有兩種組織形式:堆表(所有的記錄無序存儲),或者是聚簇索引表(所有的記錄,按照記錄主鍵進行排序存儲)。索引中存儲的是完整記錄的一個子集,用于加速記錄的查詢速度,索引的組織形式,一般均為B+樹結構。

有了這些基本知識之后,接下來讓我們創(chuàng)建一張測試表,為表新增幾個索引,然后插入幾條記錄,最后看看表的完整數(shù)據(jù)組織、存儲結構是怎么樣的。(注意:下面的實例,使用的表的結構為堆表形式,這也是Oracle/DB2/PostgreSQL等數(shù)據(jù)庫采用的表組織形式,而不是InnoDB引擎所采用的聚簇索引表。其實,表結構采用何種形式并不重要,最重要的是理解下面章節(jié)的核心,在任何表結構中均適用)

create table t1 (a int primary key, b int, c int, d int, e varchar(20));
create index idx_t1_bcd on t1(b, c, d);

insert into t1 values (4,3,1,1,'d');
insert into t1 values (1,1,1,1,'a');
insert into t1 values (8,8,8,8,'h'):
insert into t1 values (2,2,2,2,'b');
insert into t1 values (5,2,3,5,'e');
insert into t1 values (3,3,2,2,'c');
insert into t1 values (7,4,5,5,'g');
insert into t1 values (6,6,4,4,'f');

idx_t1_bcd索引上有[b,c,d]三個字段(注意:若是InnoDB類的聚簇索引表,idx_t1_bcd上還會包括主鍵a字段),不包括[a,e]字段。idx_t1_bcd索引,首先按照b字段排序,b字段相同,則按照c字段排序,以此類推。記錄在索引中按照[b,c,d]排序,但是在堆表上是亂序的,不按照任何字段排序。

SQL的where條件提取

在有了以上的t1表之后,接下來就可以在此表上進行SQL查詢了,獲取自己想要的數(shù)據(jù)。例如,考慮以下的一條SQL:

select * from t1 where b >= 2 and b < 8 and c > 1 and d != 4 and e != 'a';

一條比較簡單的SQL,一目了然就可以發(fā)現(xiàn)where條件使用到了[b,c,d,e]四個字段,而t1表的idx_t1_bcd索引,恰好使用了[b,c,d]這三個字段,那么走idx_t1_bcd索引進行條件過濾,應該是一個不錯的選擇。接下來,讓我們拋棄數(shù)據(jù)庫的思想,直接思考這條SQL的幾個關鍵性問題:

此SQL,覆蓋索引idx_t1_bcd上的哪個范圍?

起始范圍:記錄[2,2,2]是第一個需要檢查的索引項。索引起始查找范圍由b >= 2,c > 1決定。

終止范圍:記錄[8,8,8]是第一個不需要檢查的記錄,而之前的記錄均需要判斷。索引的終止查找范圍由b < 8決定;

在確定了查詢的起始、終止范圍之后,SQL中還有哪些條件可以使用索引idx_t1_bcd過濾?

根據(jù)SQL,固定了索引的查詢范圍[(2,2,2),(8,8,8))之后,此索引范圍中并不是每條記錄都是滿足where查詢條件的。例如:(3,1,1)不滿足c > 1的約束;(6,4,4)不滿足d != 4的約束。而c,d列,均可在索引idx_t1_bcd中過濾掉不滿足條件的索引記錄的。

因此,SQL中還可以使用c > 1 and d != 4條件進行索引記錄的過濾。

在確定了索引中最終能夠過濾掉的條件之后,還有哪些條件是索引無法過濾的?

此問題的答案顯而易見,e != ‘a’這個查詢條件,無法在索引idx_t1_bcd上進行過濾,因為索引并未包含e列。e列只在堆表上存在,為了過濾此查詢條件,必須將已經(jīng)滿足索引查詢條件的記錄回表,取出表中的e列,然后使用e列的查詢條件e != ‘a’進行最終的過濾。

在理解以上的問題解答的基礎上,做一個抽象,可總結出一套放置于所有SQL語句而皆準的where查詢條件的提取規(guī)則:

所有where條件均可歸納為3大類

  • Index Key (First Key & Last Key)
  • Index Filter
  • Table Filter

接下來,讓我們來詳細分析這3大類分別是如何定義,以及如何提取的。

1.Index Key

用于確定SQL查詢在索引中的連續(xù)范圍(起始范圍+結束范圍)的查詢條件,被稱之為Index Key。由于一個范圍,至少包含一個起始與一個終止,因此Index Key也被拆分為Index First Key和Index Last Key,分別用于定位索引查找的起始,以及索引查詢的終止條件。

Index First Key

用于確定索引查詢的起始范圍。提取規(guī)則:從索引的第一個鍵值開始,檢查其在where條件中是否存在,若存在并且條件是=、>=,則將對應的條件加入Index First Key之中,繼續(xù)讀取索引的下一個鍵值,使用同樣的提取規(guī)則;若存在并且條件是>,則將對應的條件加入Index First Key中,同時終止Index First Key的提??;若不存在,同樣終止Index First Key的提取。
針對上面的SQL,應用這個提取規(guī)則,提取出來的Index First Key為(b >= 2, c > 1)。由于c的條件為 >,提取結束,不包括d。

Index Last Key

Index Last Key的功能與Index First Key正好相反,用于確定索引查詢的終止范圍。提取規(guī)則:從索引的第一個鍵值開始,檢查其在where條件中是否存在,若存在并且條件是=、<=,則將對應條件加入到Index Last Key中,繼續(xù)提取索引的下一個鍵值,使用同樣的提取規(guī)則;若存在并且條件是 < ,則將條件加入到Index Last Key中,同時終止提??;若不存在,同樣終止Index Last Key的提取。

針對上面的SQL,應用這個提取規(guī)則,提取出來的Index Last Key為(b < 8),由于是 < 符號,因此提取b之后結束。

2.Index Filter

在完成Index Key的提取之后,我們根據(jù)where條件固定了索引的查詢范圍,但是此范圍中的項,并不都是滿足查詢條件的項。在上面的SQL用例中,(3,1,1),(6,4,4)均屬于范圍中,但是又均不滿足SQL的查詢條件。

Index Filter的提取規(guī)則:同樣從索引列的第一列開始,檢查其在where條件中是否存在:若存在并且where條件僅為 =,則跳過第一列繼續(xù)檢查索引下一列,下一索引列采取與索引第一列同樣的提取規(guī)則;若where條件為 >=、>、<、<= 其中的幾種,則跳過索引第一列,將其余where條件中索引相關列全部加入到Index Filter之中;若索引第一列的where條件包含 =、>=、>、<、<= 之外的條件,則將此條件以及其余where條件中索引相關列全部加入到Index Filter之中;若第一列不包含查詢條件,則將所有索引相關條件均加入到Index Filter之中。

針對上面的用例SQL,索引第一列只包含 >=、< 兩個條件,因此第一列可跳過,將余下的c、d兩列加入到Index Filter中。因此獲得的Index Filter為 c > 1 and d != 4 。

3.Table Filter

Table Filter是最簡單,最易懂,也是提取最為方便的。提取規(guī)則:所有不屬于索引列的查詢條件,均歸為Table Filter之中。
同樣,針對上面的用例SQL,Table Filter就為 e != ‘a’。

Index Key/Index Filter/Table Filter小結

SQL語句中的where條件,使用以上的提取規(guī)則,最終都會被提取到Index Key (First Key & Last Key),Index Filter與Table Filter之中。

  • Index First Key,只是用來定位索引的起始范圍,因此只在索引第一次Search Path(沿著索引B+樹的根節(jié)點一直遍歷,到索引正確的葉節(jié)點位置)時使用,一次判斷即可;
  • Index Last Key,用來定位索引的終止范圍,因此對于起始范圍之后讀到的每一條索引記錄,均需要判斷是否已經(jīng)超過了Index Last Key的范圍,若超過,則當前查詢結束;
  • Index Filter,用于過濾索引查詢范圍中不滿足查詢條件的記錄,因此對于索引范圍中的每一條記錄,均需要與Index Filter進行對比,若不滿足Index Filter則直接丟棄,繼續(xù)讀取索引下一條記錄;
  • Table Filter,則是最后一道where條件的防線,用于過濾通過前面索引的層層考驗的記錄,此時的記錄已經(jīng)滿足了Index First Key與Index Last Key構成的范圍,并且滿足Index Filter的條件,回表讀取了完整的記錄,判斷完整記錄是否滿足Table Filter中的查詢條件,同樣的,若不滿足,跳過當前記錄,繼續(xù)讀取索引的下一條記錄,若滿足,則返回記錄,此記錄滿足了where的所有條件,可以返回給前端用戶。

結語

在讀完、理解了以上內(nèi)容之后,詳細大家對于數(shù)據(jù)庫如何提取where中的查詢條件,如何將where中的查詢條件提取為Index Key,Index Filter,Table Filter有了深刻的認識。以后在撰寫SQL語句時,可以對照表的定義,嘗試自己提取對應的where條件,與最終的SQL執(zhí)行計劃對比,逐步強化自己的理解。

同時,我們也可以回答文章開始提出的一個問題:MySQL 5.6中引入的Index Condition Pushdown,究竟是將什么Push Down到索引層面進行過濾呢?對了,答案是Index Filter。在MySQL 5.6之前,并不區(qū)分Index Filter與Table Filter,統(tǒng)統(tǒng)將Index First Key與Index Last Key范圍內(nèi)的索引記錄,回表讀取完整記錄,然后返回給MySQL Server層進行過濾。而在MySQL 5.6之后,Index Filter與Table Filter分離,Index Filter下降到InnoDB的索引層面進行過濾,減少了回表與返回MySQL Server層的記錄交互開銷,提高了SQL的執(zhí)行效率。

到此這篇關于MySQL WHERE語句用法小結的文章就介紹到這了,更多相關MySQL WHERE 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL查詢優(yōu)化與事務實戰(zhàn)教程

    MySQL查詢優(yōu)化與事務實戰(zhàn)教程

    文章介紹了MySQL查詢語法與事務管理,涵蓋InnoDB/MyISAM區(qū)別、多表連接、分組統(tǒng)計、子查詢、分頁技術,及事務四大特性和隔離級別(讀未提交、讀已提交、可重復讀、可串行化),并強調了參數(shù)化查詢的重要性以防范SQL注入,感興趣的朋友一起看看吧
    2025-07-07
  • MySQL thread_stack連接線程的優(yōu)化

    MySQL thread_stack連接線程的優(yōu)化

    當有新的連接請求時,MySQL首先會檢查Thread Cache中是否存在空閑連接線程,如果存在則取出來直接使用,如果沒有空閑連接線程,才創(chuàng)建新的連接線程
    2017-04-04
  • MySQL  外鍵(foreign key)約束的作用和使用

    MySQL  外鍵(foreign key)約束的作用和使用

    外鍵約束是用于建立兩個表之間關系的一種約束,本文主要介紹了MySQL外鍵約束詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • mysql查線上數(shù)據(jù)注意數(shù)據(jù)庫的隔離級別

    mysql查線上數(shù)據(jù)注意數(shù)據(jù)庫的隔離級別

    數(shù)據(jù)庫的隔離級別關乎事務對其他并發(fā)事務的可見性及其對數(shù)據(jù)庫的影響,隔離級別的選擇決定了并發(fā)性能和數(shù)據(jù)一致性的平衡,SQL標準定義了四種隔離級別,每種級別都有不同的應用場景和防止并發(fā)問題的能力,感興趣的可以了解一下
    2024-10-10
  • MYSQL 左連接右連接和內(nèi)連接的詳解及區(qū)別

    MYSQL 左連接右連接和內(nèi)連接的詳解及區(qū)別

    這篇文章主要介紹了MYSQL 左連接右連接和內(nèi)連接的詳解及區(qū)別的相關資料,需要的朋友可以參考下
    2016-11-11
  • 服務器MYSQL啟動/停止/重啟命令方式

    服務器MYSQL啟動/停止/重啟命令方式

    文章介紹了查看MySQL版本的兩種方法及啟動/停止/重啟命令,提示5.5后服務名改為mysql,舊版本用mysqld;現(xiàn)代系統(tǒng)推薦systemctl替代service,需注意命令差異
    2025-09-09
  • MySQL入門(四) 數(shù)據(jù)表的數(shù)據(jù)插入、更新、刪除

    MySQL入門(四) 數(shù)據(jù)表的數(shù)據(jù)插入、更新、刪除

    這篇文章主要介紹了mysql數(shù)據(jù)庫中表的插入、更新、刪除非常簡單,但是簡單的也要學習,細節(jié)決定成敗,需要的朋友可以參考下
    2018-07-07
  • MySQL重連連接丟失:The last packet successfully received from the server的原因及解決方案

    MySQL重連連接丟失:The last packet successfully 

    在開發(fā)和運維MySQL數(shù)據(jù)庫應用時,經(jīng)常會遇到“連接丟失”或“重連失敗”的問題,這類問題不僅會影響應用程序的穩(wěn)定性,還可能導致數(shù)據(jù)不一致等嚴重后果,本文將探討MySQL連接丟失的原因、如何診斷此類問題以及采取哪些措施來解決或預防,需要的朋友可以參考下
    2025-02-02
  • 解決MySQL去除密碼登錄告警的問題

    解決MySQL去除密碼登錄告警的問題

    這篇文章主要介紹了MySQL去除密碼登錄告警的問題,解決方法是使用mysql_config_editor,本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • mysql中提高Order by語句查詢效率的兩個思路分析

    mysql中提高Order by語句查詢效率的兩個思路分析

    在MySQL數(shù)據(jù)庫中,Order by語句的使用頻率是比較高的。但是眾所周知,在使用這個語句時,往往會降低數(shù)據(jù)查詢的性能。
    2011-03-03

最新評論

太原市| 昌黎县| 周宁县| 平远县| 新源县| 新巴尔虎右旗| 塔河县| 乐清市| 南平市| 同江市| 南和县| 闵行区| 龙州县| 松潘县| 平果县| 临漳县| 永仁县| 东阳市| 长武县| 池州市| 蒲江县| 卓尼县| 敦煌市| 高安市| 余庆县| 江口县| 贵南县| 海原县| 卢龙县| 自治县| 娱乐| 阿瓦提县| 无棣县| 法库县| 淳化县| 宣武区| 清镇市| 松滋市| 章丘市| 平湖市| 牙克石市|