mysql的一個select需要經歷什麼查詢出結果

2022-01-30 IT入門

作者:小胖學編程
連結:https://www.jianshu.com/p/b3add5abb7c1

長按下方二維碼↓↓↓

回復 527252免費獲取


 

問題

一般會遇見如下的問題:

mysql框架有幾個組件,各有什麼作用?
見下文

server層和存儲引擎層各是什麼作用?
存儲引擎層完成的是數據的存儲和提取;
server完成的是:跨存儲引擎的功能,例如存儲過程。觸發器,視圖。

you have an error in your SQL syntax這個報錯是詞法分析還是語法分析報錯?
語法分析報錯,詞法分析目的是識別出sql裡面的字符串代表什麼,語法分析的目的是識別出sql語句是否滿足mysql語法。

對於表的操作權限驗證是在哪裡進行的?
執行器驗證

執行器的執行查詢語句的流程是什麼樣的?
見下文

為什麼不在優化器前做權限判斷?
因為查詢的表不一定是sql語句,比如觸發器。此時優化器階段並不知道,只能在執行階段知道。

一個select查詢語句的執行流程?
見下文

分析

mysql可以分為server層和存儲引擎層兩部分。

Server層包括:連接器、查詢緩存、分析器、優化器、執行器等,涵蓋了mysql大多數核心服務功能。以及所有內置函數(日期、時間、數學加密函數)。所有跨存儲引擎的功能都在這一層實現,比如 存儲過程、觸發器、視圖。

而存儲引擎層負責數據的存儲和提取,其架構模式是插件式的,支持innoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從 MySQL 5.5.5 版本開始成為了默認存儲引擎。

第一步:連接器(建立連接、獲取權限、維持和管理連接)

驗證用戶名密碼

獲取權限列表

第二步:緩存(緩存sql結果)

Mysql8.0版本直接將查詢緩存整塊功能都刪掉了。因為查詢緩存失效非常頻繁,只有有對一個表的更新操作,那麼這個表所有緩存都會被清空。故在高版本,刪除了緩存的功能。

第三步:分析器(對sql進行詞法分析、語法分析、語義分析)

如果沒有命中查詢緩存,就要開始真正執行語句了。

分析器首先會進行sql解析,分為如下幾個步驟:

1. 詞法分析:需要識別出sql裡面的字符串分別是什麼,代表什麼?

例如select * from t where ID=10

mysql將select關鍵字識別出來,這是一個查詢語句;
mysql將字符串t識別成表名t;
mysql將字符串id識別成列id

2. 語法分析:判斷sql語句是否滿足mysql語法

語法分析主要是分析輸入的sql語法合不合法。分析select、from、where是否複合語法。

如果將select打成slect,那麼這個階段會拋出You have an error in your SQL syntax;

3. 語義分析:對sql中的表,欄位屬性等內容進行檢查是否存在

例如:對資料庫不存在的列「id」,會拋出不存在列的錯誤,這是分析器在語義分析拋出來的。

第四步:優化器(執行方案選擇和索引策略選擇)

經過分析器分析之後,mysql就知道你要做什麼。

當有多種索引、有多種執行方案可以執行時,優化器就會考慮選擇走什麼索引(或者不走索引),走哪種執行方案,效率會更高。總的來說:優化sql語句的執行,最終生成執行計劃。

第五步:執行器(調用存儲引擎接口獲取記錄並返回給客戶端)

分析器知道了你要做什麼,優化器知道了該怎麼做,執行器就開始執行:

判斷用戶「對表t」有沒有查詢權限(剛開始建立連接已經查出所有權限),沒有權限報錯,有則進入下一步;

有權限就會打開表繼續執行,執行器會根據表的引擎定義,去使用這個引擎提供的接口。

調用InnoDB引擎接口,判斷這一行id是不是10,如果不是跳過,如果是則將這行存在結果集中。

調用引擎接口取「下一行」,重複相同的判斷邏輯,直至取到最後一行。

執行器將上述遍歷過程中所有滿足條件的行組成結果集,並且返回給客戶端。

長按下方二維碼↓↓↓

回復 527252免費獲取


 

相關焦點

  • mysql資料庫select查詢語句
    select的相關語句在mysql中用的非常多,介紹一下。select語句的介紹1 select * from 表名;*(代表表中的所有欄位)2 select distinct 欄位名 from表名 ; distinct 去掉重複欄位3 select * from 表名 where 條件 ;where 添加查詢的限制條件比較運算符 >、<、>=、<=、!
  • 玩轉Mysql系列 - 第6篇:select查詢基礎篇
    基本語法 select 查詢的列 from 表名;注意:select語句中不區分大小寫,SELECT和select、FROM和from效果一樣。查詢的結果放在一個表格中,表格的第1行稱為列頭,第2行開始是數據,類屬於一個二維數組。
  • mysql結果去重和條件查詢where的使用
    等等下面介紹今天的話題,在mysql查詢結果中去重,比如一個表中欄位關係是一對多,或者多對多的關係。我們需要用到關鍵詞DISTINCT實際運用到的案例在項目中一個ip訪問多次你的網站,但是結果裡面不需要看到重複的ip,這個時候DISTINCT就需要排上用處了。我們上demo實際運行一下。
  • 《MySQL》系列 - select 語句是怎麼執行的?
    select * from user where id = 1; 01 mysql 架構概覽要想理解這個問題就必須要知道 mysql 的內部架構。使用特定時間,或者程序判斷執行一個佔用內存大的操作後,斷開連接。之後需要操作就重連。mySQL 5.7 或以上版本,可以在每次執行一個佔用內存大的操作後,執行 mysql_reset_connection 來重新連接資源,此時不需重連或重新做權限認證,但會把連接狀態恢復到剛創建完時。
  • MySQL 優化案例 - select count-愛可生
    貌似也沒有什麼問題,走索引了呀!那麼是不是真的就沒問題呢?四、原理為了找到答案,通過 Google 查找 MySQL 下 select count(*)的原理,找到了答案。這邊省略過程,直接上結果。在 select count(*)的查詢過程中,只需要將二級索引讀取到內存緩衝區,只有幾十 MB 的數據量,所以速度會非常快。舉個形象的比喻,我們想知道一本書的頁數:走聚集索引:從第一頁翻到最後一頁,知道總頁數;走二級索引:通過目錄直接知道總頁數。五、驗證創建二級索引後,再次執行 SQL 及查看執行計劃。
  • mysql中使用select的正確姿勢
    取博客http://flysnowxf.iteye.com/blog/1125032的測試結果mysql 5.1.37 表記錄數41,547,002,即4000w行 使用遠程客戶端取1000條數據,統計時間:SELECT * FROM `dmsp`.
  • 故障分析 | MySQL 優化案例 - select count(*)
    貌似也沒有什麼問題,走索引了呀!那麼是不是真的就沒問題呢?為了找到答案,通過 Google 查找 MySQL 下 select count(*) 的原理,找到了答案。這邊省略過程,直接上結果。在 select  count(*) 的查詢過程中,只需要將二級索引讀取到內存緩衝區,只有幾十 MB 的數據量,所以速度會非常快。走聚集索引:從第一頁翻到最後一頁,知道總頁數;走二級索引:通過目錄直接知道總頁數。創建二級索引後,再次執行 SQL 及查看執行計劃。
  • MySQL如何完成一次查詢?
    那麼從發出一條sql指令到返回結果mysql都做了什麼事情呢?mysql完成一次查詢過程是比較複雜的,在說明查詢過程前先介紹一下它的基礎概念和結構原理來幫助理解。下面從四個方面介紹,分別是mysql語句,mysql結構原理,mysql查詢過程,最後設置幾個有趣問題。
  • MySQL全面瓦解—子查詢和組合查詢
    子查詢分類 按照查詢的返回結果   1、單行單列(標量子查詢):返回的是一個具體列的內容,可以理解為一個單值數據;  2、單行多列(行子查詢):返回一行數據中多個列的內容;  3、多行單列(列子查詢):返回多行記錄之中同一列的內容,相當於給出了一個操作範圍;
  • MySQL 這該死的 「IN (子查詢)」
    *,(SELECT MAX(id) FROM t2 WHERE t1.id = t2.id) FROM t1 WHERE t1.id%2 = 0;從上我們不難發現:對於「非關聯子查詢」,子查詢只用執行一次,執行完後結果會被存入到臨時表,不管這一次是走上索引了,還是全表掃描,最大成本是一次全表掃描。
  • 學習MySQL的select語句
    >都可以得到正確的結果,但有時分開寫或許能 更明了一點,特別是當sql語句比較長時。批量查詢數據可以用in 來實現 $sql="select * from article where id  ;in(1,3,5)"使用concat連接查詢的結果$sql="select concat(id,"-",con)  as res from article where id=1"返回 "1-article content"
  • MySQL聊聊SELECT必須知道的基礎知識
    一、前言select語句可以說是mysql中最常用的語句了,除了select還有insert、delete、update等關鍵詞,這些關鍵詞是mysql的保留詞,我們在定義表名,欄位名,變量名的時候不要使用這些保留詞。
  • 教你快速實現 MySQL查詢結果的分頁顯示
    在mysql中利用select語句的一個特性就可以很方便地實現查詢結果的分頁,select語句的語法: > 以下為引用的內容:SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [HIGH_PRIORITY] [DISTINCT | DISTINCTROW | ALL] select_expression,...
  • MySQL:SELECT COUNT 小結
    如果您正在學習Spring Boot,推薦一個連載多年還在繼續更新的免費教程:http://blog.didispace.com/spring-boot-learning-2x/所以執行以下數據會出現這樣的結果(這邊是故意給component欄位設置了幾個null值):select COUNT(*),COUNT(1),COUNT(component) from
  • mysql查詢優化explain命令詳解
    explain翻譯即解釋,就是看mysql語句的查詢解釋計劃,從解釋計劃我們能很清楚的看到解釋的語句有沒有合理用到索引,掃描了多少行數,有沒有觸及全表掃描、用到臨時表等影響慢查詢的原因。使用很簡單,如explain select * from user ...
  • 拿什麼拯救你,我的MySQL子查詢
    mysql的子查詢一直被人所詬病,主要原因是mysql子查詢奉行的是「由外到內」的政策。
  • Mysql 手工注入【常規union查詢篇】
    下面是注入mysql時經常會用到的一些單行函數,熟練使用是靈活注入的前提,尤其是在對抗一些waf的時候字符串連接函數,將多個字符串連接成一個字符串,注意,中間只要字符串有一個為空,最後結果也為空 concat(str1,str2,str3.
  • MYSQL 從項目經理的一次查詢,到MYSQL 查詢語句優化方法多
    事情的起因是,我們的一個項目經理需要對一個資料庫的信息進行查詢,SQL 人家都會寫的。
  • mysql的查詢、子查詢及連接查詢
    count(a),無論a是什麼,都只是數一行;count時,每遇到一行,就數一個a,跟條件無關!查詢結果集可以當成表看待。臨時表要使用一個別名。)然後將這個結果集作為一張臨時表,巧妙的使用group by 查詢出每個類別下的第一條記錄,即為每個類別下商品id最大。
  • 從Web查詢資料庫之PHP與MySQL篇
    查詢資料庫 要執行資料庫查詢,首先應構造查詢語句:$query = select * from user;然後運行 $result = $db->query($query);或者$result = mysqli_query($db,$query); 面向對象版本將返回一個結果對象;過程版本將返回一個結果資源。無論何種方法都將結果保存在$result變量中工以後使用。