曰本美女∴一区二区特级A级黄色大片, 国产亚洲精品美女久久久久久2025, 页岩实心砖-高密市宏伟建材有限公司, 午夜小视频在线观看欧美日韩手机在线,国产人妻奶水一区二区,国产玉足,妺妺窝人体色WWW网站孕妇,色综合天天综合网中文伊,成人在线麻豆网观看

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一條SQL如何被MySQL架構(gòu)中的各個(gè)組件操作執(zhí)行的?

OSC開(kāi)源社區(qū) ? 來(lái)源:OSCHINA 社區(qū) ? 2023-05-12 14:41 ? 次閱讀

1. 單表查詢(xún) SQL 在 MySQL 架構(gòu)中的各個(gè)組件的執(zhí)行過(guò)程

簡(jiǎn)單用一張圖說(shuō)明下,MySQL 架構(gòu)有哪些組件,接下來(lái)給大家用 SQL 語(yǔ)句分析

f014f6fe-f089-11ed-90ce-dac502259ad0.png

假如 SQL 語(yǔ)句是這樣

SELECT class_no FROM student WHERE name = 'lcy' AND age > 18 GROUP BY class_no
其中 name 為索引,我們按照時(shí)間順序來(lái)分析一下

1. 客戶(hù)端:客戶(hù)端(如 MySQL 命令行工具、Navicat、MySQL Workbench 或其他應(yīng)用程序)發(fā)送 SQL 查詢(xún)到 MySQL 服務(wù)器。

2. 連接器:連接器負(fù)責(zé)與客戶(hù)端建立連接、管理連接和維護(hù)連接。當(dāng)客戶(hù)端連接到 MySQL 服務(wù)器時(shí),連接器驗(yàn)證客戶(hù)端的用戶(hù)名和密碼,然后分配一個(gè)線(xiàn)程來(lái)處理客戶(hù)端的請(qǐng)求。

3. 查詢(xún)緩存:查詢(xún)緩存用于緩存先前執(zhí)行過(guò)的查詢(xún)及其結(jié)果。當(dāng)收到新的查詢(xún)請(qǐng)求時(shí),MySQL 首先檢查查詢(xún)緩存中是否已有相同的查詢(xún)及其結(jié)果。如果查詢(xún)緩存中有匹配的查詢(xún)結(jié)果,MySQL 將直接返回緩存的結(jié)果,而無(wú)需再次執(zhí)行查詢(xún)。但是,如果查詢(xún)緩存中沒(méi)有匹配的查詢(xún)結(jié)果,MySQL 將繼續(xù)執(zhí)行查詢(xún)。查詢(xún)緩存在 MySQL 8.0 中已被移除,不詳細(xì)解釋。

4. 分析器:

解析查詢(xún)語(yǔ)句,檢查語(yǔ)法。

驗(yàn)證表名和列名的正確性。

生成查詢(xún)樹(shù)。

5. 優(yōu)化器:分析查詢(xún)樹(shù),考慮各種執(zhí)行計(jì)劃,估算不同執(zhí)行計(jì)劃的成本,選擇最佳的執(zhí)行計(jì)劃。在這個(gè)例子中,優(yōu)化器可能會(huì)選擇使用 name 索引進(jìn)行查詢(xún),因?yàn)?name 是索引列。

6. 執(zhí)行器:根據(jù)優(yōu)化器選擇的執(zhí)行計(jì)劃,向存儲(chǔ)引擎發(fā)送請(qǐng)求,獲取滿(mǎn)足條件的數(shù)據(jù)行。

7. 存儲(chǔ)引擎(如 InnoDB):

負(fù)責(zé)實(shí)際執(zhí)行索引掃描,如在 student 表的 name 索引上進(jìn)行等值查詢(xún),因查詢(xún)?nèi)苛?,涉及到回表訪問(wèn)磁盤(pán)。

在訪問(wèn)磁盤(pán)之前,先檢查 InnoDB 的緩沖池(Buffer Pool)中是否已有所需的數(shù)據(jù)頁(yè)。如果緩沖池中有符合條件的數(shù)據(jù)頁(yè),直接使用緩存的數(shù)據(jù)。如果緩沖池中沒(méi)有所需的數(shù)據(jù)頁(yè),從磁盤(pán)加載數(shù)據(jù)頁(yè)到緩沖池中。

8. 執(zhí)行器:

對(duì)于每個(gè)找到的記錄,再次判斷記錄是否滿(mǎn)足索引條件 name。這是因?yàn)榛谒饕龡l件加載到內(nèi)存中是數(shù)據(jù)頁(yè),數(shù)據(jù)頁(yè)中也有可能包含不滿(mǎn)足索引條件的記錄,所以還要再判斷一次 name 條件,滿(mǎn)足 name 條件則繼續(xù)判斷 age > 18 過(guò)濾條件。

根據(jù) class_no 對(duì)滿(mǎn)足條件的記錄進(jìn)行分組。

執(zhí)行器將處理后的結(jié)果集返回給客戶(hù)端。

在整個(gè)查詢(xún)執(zhí)行過(guò)程中,這些組件共同協(xié)作以高效地執(zhí)行查詢(xún)??蛻?hù)端負(fù)責(zé)發(fā)送查詢(xún),連接器管理客戶(hù)端連接,查詢(xún)緩存嘗試重用先前查詢(xún)結(jié)果,解析器負(fù)責(zé)解析查詢(xún),優(yōu)化器選擇最佳執(zhí)行計(jì)劃,執(zhí)行器執(zhí)行優(yōu)化器選擇的計(jì)劃,存儲(chǔ)引擎(如 InnoDB)負(fù)責(zé)管理數(shù)據(jù)存儲(chǔ)和訪問(wèn)。這些組件的協(xié)同作用使得 MySQL 能夠高效地執(zhí)行查詢(xún)并返回結(jié)果集。 根據(jù)索引列過(guò)濾條件加載索引的數(shù)據(jù)頁(yè)到內(nèi)存這個(gè)操作是存儲(chǔ)引擎做的。加載到內(nèi)存中之后,執(zhí)行器會(huì)進(jìn)行索引列和非索引列的過(guò)濾條件判斷。

2. SELECT 的各個(gè)關(guān)鍵字在哪里執(zhí)行?

根據(jù)執(zhí)行順序,如下:

(1)FROM:FROM 子句用于指定查詢(xún)所涉及的數(shù)據(jù)表。在查詢(xún)執(zhí)行過(guò)程中,執(zhí)行器需要根據(jù)優(yōu)化器選擇的執(zhí)行計(jì)劃從存儲(chǔ)引擎中獲取指定表的數(shù)據(jù)。

(2)ON:ON 子句用于指定連接條件,它通常與 JOIN 子句一起使用。在查詢(xún)執(zhí)行過(guò)程中,執(zhí)行器會(huì)根據(jù) ON 子句中的條件從存儲(chǔ)引擎獲取滿(mǎn)足條件的記錄。如果連接條件涉及到索引列,存儲(chǔ)引擎可能會(huì)使用索引進(jìn)行優(yōu)化。

(3)JOIN:JOIN 子句用于指定表之間的連接方式(如 INNER JOIN, LEFT JOIN 等)。在查詢(xún)執(zhí)行過(guò)程中,執(zhí)行器會(huì)根據(jù)優(yōu)化器選擇的執(zhí)行計(jì)劃,從存儲(chǔ)引擎中獲取需要連接的表的數(shù)據(jù)。然后,執(zhí)行器根據(jù) JOIN 子句的類(lèi)型和 ON 子句中的連接條件,對(duì)數(shù)據(jù)進(jìn)行連接操作。

(4)WHERE:執(zhí)行器對(duì)從存儲(chǔ)引擎返回的數(shù)據(jù)進(jìn)行過(guò)濾,只保留滿(mǎn)足 WHERE 子句條件的記錄。部分過(guò)濾條件如果涉及到索引,在存儲(chǔ)引擎層就已經(jīng)進(jìn)行了過(guò)濾。

(5)GROUP BY:執(zhí)行器對(duì)滿(mǎn)足 WHERE 子句條件的記錄按照 GROUP BY 子句中指定的列進(jìn)行分組。

(6)HAVING:執(zhí)行器在進(jìn)行分組后,根據(jù) HAVING 子句條件對(duì)分組后的記錄進(jìn)行進(jìn)一步過(guò)濾。

(7)SELECT:執(zhí)行器根據(jù)優(yōu)化器選擇的執(zhí)行計(jì)劃來(lái)獲取查詢(xún)結(jié)果。

(8)DISTINCT:執(zhí)行器對(duì)查詢(xún)結(jié)果進(jìn)行去重,只返回不重復(fù)的記錄。

(9)ORDER BY:執(zhí)行器對(duì)查詢(xún)結(jié)果按照 ORDER BY 子句中指定的列進(jìn)行排序。

(10)LIMIT:執(zhí)行器根據(jù) LIMIT 子句中指定的限制條件對(duì)查詢(xún)結(jié)果進(jìn)行截?cái)啵环祷夭糠钟涗?/p>

3. 表關(guān)聯(lián)查詢(xún) SQL 在 MySQL 架構(gòu)中的各個(gè)組件的執(zhí)行過(guò)程

SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM student s
JOIN score sc ON s.id = sc.student_id
WHERE s.age > 18 AND sc.subject = 'math' AND sc.score > 80;
這個(gè)例子中,student_id 和 subject 是聯(lián)合索引,age 是索引。 我們按照時(shí)間順序來(lái)分析一下

1. 連接器:當(dāng)客戶(hù)端連接到 MySQL 服務(wù)器時(shí),連接器負(fù)責(zé)建立和管理連接。它驗(yàn)證客戶(hù)端提供的用戶(hù)名和密碼,確定客戶(hù)端具有相應(yīng)的權(quán)限,然后建立連接。

2. 查詢(xún)緩存:MySQL 服務(wù)器在處理查詢(xún)之前,會(huì)先檢查查詢(xún)緩存。如果查詢(xún)緩存中已經(jīng)存在相同的查詢(xún)及其結(jié)果集,服務(wù)器將直接返回緩存中的結(jié)果,而不再執(zhí)行后續(xù)的查詢(xún)處理。由于查詢(xún)緩存在 MySQL 8.0 中已被移除,我們?cè)谶@個(gè)示例中不再詳細(xì)討論。

3. 解析器:解析器的主要任務(wù)是解析 SQL 查詢(xún)語(yǔ)句,確保查詢(xún)語(yǔ)法正確。解析器會(huì)將查詢(xún)語(yǔ)句分解成多個(gè)組成部分,例如表、列、條件等。在這個(gè)示例中,解析器會(huì)識(shí)別出涉及的表(student 和 score)以及需要的列(id、name、age、subject、score)。

4. 優(yōu)化器:優(yōu)化器的職責(zé)是根據(jù)解析器提供的信息生成執(zhí)行計(jì)劃。它會(huì)分析多種可能的執(zhí)行策略,并選擇成本最低的策略。在這個(gè)示例中,優(yōu)化器可能會(huì)分析各種表掃描和索引掃描的組合,最終選擇一種成本最低的執(zhí)行計(jì)劃。

5. 執(zhí)行器:根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃處理查詢(xún),向存儲(chǔ)引擎發(fā)送請(qǐng)求,獲取滿(mǎn)足條件的數(shù)據(jù)行。

6. 存儲(chǔ)引擎(如 InnoDB):存儲(chǔ)引擎負(fù)責(zé)管理數(shù)據(jù)的存儲(chǔ)和檢索。

存儲(chǔ)引擎首先接收來(lái)自執(zhí)行器的請(qǐng)求。請(qǐng)求可能包括獲取滿(mǎn)足查詢(xún)條件的數(shù)據(jù)行,以及使用哪種掃描方法(如全表掃描或索引掃描)。

假設(shè)執(zhí)行器已經(jīng)決定使用索引掃描。在這個(gè)示例中,存儲(chǔ)引擎可能會(huì)先對(duì) student 表進(jìn)行索引掃描(使用 age 索引),然后對(duì) score 表進(jìn)行索引掃描(使用 student_id 和 subject 的聯(lián)合索引)。

存儲(chǔ)引擎會(huì)根據(jù)請(qǐng)求查詢(xún)相應(yīng)的索引結(jié)構(gòu)。在 student 表中,存儲(chǔ)引擎會(huì)找到滿(mǎn)足 age > 18 條件的記錄。在 score 表中,存儲(chǔ)引擎會(huì)找到滿(mǎn)足 subject = 'math' AND score > 80 條件的記錄。

一旦找到了滿(mǎn)足條件的記錄,存儲(chǔ)引擎需要將這些記錄所在的數(shù)據(jù)頁(yè)從磁盤(pán)加載到內(nèi)存中。存儲(chǔ)引擎首先檢查緩沖池(InnoDB Buffer Pool),看這些數(shù)據(jù)頁(yè)是否已經(jīng)存在于內(nèi)存中。如果已經(jīng)存在,則無(wú)需再次從磁盤(pán)加載。如果不存在,存儲(chǔ)引擎會(huì)將這些數(shù)據(jù)頁(yè)從磁盤(pán)加載到緩沖池中。

加載到緩沖池中的記錄可以被多個(gè)查詢(xún)共享,這有助于提高查詢(xún)效率。

7. 執(zhí)行器:處理連接、排序、聚合、過(guò)濾等操作。

在內(nèi)存中執(zhí)行連接操作,將 student 表和 score 表的數(shù)據(jù)行連接起來(lái)。

對(duì)連接后的結(jié)果集進(jìn)行過(guò)濾,只保留滿(mǎn)足查詢(xún)條件(age > 18、subject = 'math'、score > 80)的數(shù)據(jù)行。

將過(guò)濾后的數(shù)據(jù)行作為查詢(xún)結(jié)果返回給客戶(hù)端。

前面說(shuō)過(guò),根據(jù)存儲(chǔ)引擎根據(jù)索引條件加載到內(nèi)存的數(shù)據(jù)頁(yè)有多數(shù)據(jù),可能有不滿(mǎn)足索引條件的數(shù)據(jù),如果執(zhí)行器不再次進(jìn)行索引條件判斷, 則無(wú)法判斷哪些記錄滿(mǎn)足索引條件的,雖然在存儲(chǔ)引擎判斷過(guò)了,但是在執(zhí)行器還是會(huì)有索引條件 age > 18、subject = 'math'、score > 80 的判斷。

4. LEFT JOIN 將過(guò)濾條件放在子查詢(xún)中再關(guān)聯(lián)和放在 WHERE 子句上有什么區(qū)別?

先看例子 查詢(xún) 1

SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id
WHERE s.age > 18 AND sc.subject = 'math' AND sc.score > 80;

查詢(xún) 2

SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM (SELECT id, name, age FROM student WHERE age > 18) s
LEFT JOIN (SELECT student_id, subject, score FROM score WHERE subject = 'math' AND score > 80) sc 
ON s.id = sc.student_id

查詢(xún) 3

SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id AND s.age > 18 AND sc.subject = 'math' AND sc.score > 80;
先給出結(jié)論:查詢(xún) 2 和 3 是一樣的,也就是過(guò)濾條件放在子查詢(xún)中和放在 on 上面是一樣的,后面就只討論查詢(xún) 1、2,查詢(xún) 1 和查詢(xún) 2 是不一樣的,過(guò)濾條件放在 where 子句中和放在子查詢(xún)?cè)訇P(guān)聯(lián)查詢(xún)出的結(jié)果也是有區(qū)別的。 分析一下 從運(yùn)行結(jié)果來(lái)看,對(duì)于查詢(xún) 1
SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id
WHERE s.age > 18 AND sc.subject = 'math' AND sc.score > 80;
在這個(gè)查詢(xún)中,首先執(zhí)行 LEFT JOIN,將 student 表和 score 表連接起來(lái)。連接操作是基于 s.id = sc.student_id 條件進(jìn)行的。LEFT JOIN 操作會(huì)保留左表(student 表)中的所有行,即使它們?cè)谟冶恚╯core 表)中沒(méi)有匹配的行。如果右表中沒(méi)有匹配的行,那么右表的列將顯示為 NULL。 然后,WHERE 子句會(huì)過(guò)濾連接后的結(jié)果集,只保留那些滿(mǎn)足 s.age > 18 and sc.subject = 'math' and sc.score > 80 條件的行。這意味著,右表為 NULL 的記錄將被排除,因?yàn)橛冶淼倪^(guò)濾條件 sc.subject = 'math' and sc.score > 80 條件不滿(mǎn)足。 對(duì)于查詢(xún) 2:
SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM (select id, name, age from student where age > 18) s
LEFT JOIN (select subject, score from score where subject = 'math' AND score > 80) sc 
ON s.id = sc.student_id
在這個(gè)查詢(xún)中,我們首先執(zhí)行兩個(gè)子查詢(xún)。第一個(gè)子查詢(xún)從 student 表中選擇所有 age > 18 的行,而第二個(gè)子查詢(xún)從 score 表中選擇所有 subject = 'math' and score > 80 的行。這意味著,在進(jìn)行連接操作之前,我們已經(jīng)對(duì)兩個(gè)表分別進(jìn)行了過(guò)濾。 接下來(lái),執(zhí)行 LEFT JOIN 操作,將過(guò)濾后的 s 和 sc 子查詢(xún)的結(jié)果集連接起來(lái),基于 s.id = sc.student_id 條件。因?yàn)?LEFT JOIN 操作會(huì)保留左表(s 子查詢(xún)的結(jié)果集)中的所有行,右表為 NULL 的記錄包含了。 結(jié)果差異: 查詢(xún) 1 和查詢(xún) 2 的主要區(qū)別在于 WHERE 子句和子查詢(xún)的使用。

查詢(xún) 1 在連接操作后應(yīng)用過(guò)濾條件,這可能導(dǎo)致右表為 NULL 的關(guān)聯(lián)記錄因?yàn)橛冶淼倪^(guò)濾條件而被排除在外。而查詢(xún) 2 在連接操作之前就已經(jīng)過(guò)濾了表中的數(shù)據(jù),這意味著查詢(xún)結(jié)果會(huì)包含所有左表過(guò)濾條件的記錄,以及右表過(guò)濾條件的記錄和 NULL 的記錄。 如果查詢(xún) 1 想保留右表為 NULL 的記錄,只需要改為 WHERE s.age > 18 AND (sc.student_id is null OR (sc.subject = 'math' AND sc.score> 80)); 這樣查詢(xún) 1 和 2 會(huì)有相同的結(jié)果集。 我們分析一下這兩個(gè)查詢(xún)?cè)?MySQL 架構(gòu)中各個(gè)組件中執(zhí)行的區(qū)別 對(duì)于查詢(xún) 1:
SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id
WHERE s.age > 18 AND sc.subject = 'math' AND sc.score > 80;

連接器:客戶(hù)端與服務(wù)器建立連接。

查詢(xún)緩存:檢查緩存是否存在此查詢(xún)的結(jié)果。如果有,直接返回結(jié)果。否則,繼續(xù)執(zhí)行。

解析器:解析查詢(xún)語(yǔ)句,檢查語(yǔ)法是否正確。

優(yōu)化器:對(duì)查詢(xún)進(jìn)行優(yōu)化,生成執(zhí)行計(jì)劃,決定連接和過(guò)濾條件的順序等。

執(zhí)行器:開(kāi)始請(qǐng)求執(zhí)行查詢(xún)。

存儲(chǔ)引擎(InnoDB):從磁盤(pán)或者緩沖池讀取滿(mǎn)足條件的數(shù)據(jù)行(s.id = sc.student_id),因?yàn)槭?left join,所以即便 sc.student_id 為 null 也會(huì)被關(guān)聯(lián)。

執(zhí)行器:將從存儲(chǔ)引擎獲取的數(shù)據(jù)行進(jìn)行左連接,應(yīng)用過(guò)濾條件 s.age > 18 and sc.subject = 'math' and sc.score > 80 進(jìn)行過(guò)濾,將結(jié)果集返回給客戶(hù)端。

當(dāng)查詢(xún)包含索引列的條件時(shí),MySQL 的存儲(chǔ)引擎會(huì)首先利用索引在磁盤(pán)上定位到滿(mǎn)足索引條件的記錄。接著,將這些索引數(shù)據(jù)對(duì)應(yīng)的數(shù)據(jù)頁(yè)加載到內(nèi)存中的緩沖池。然后,執(zhí)行器在內(nèi)存中對(duì)這些記錄進(jìn)行進(jìn)一步的過(guò)濾,根據(jù)索引條件和非索引列的條件來(lái)過(guò)濾數(shù)據(jù)。

當(dāng)查詢(xún)涉及到非聚集索引時(shí),需要回表的操作會(huì)導(dǎo)致聚集索引和非聚集索引都被加載到內(nèi)存中。但是,如果查詢(xún)只涉及到聚集索引(如主鍵查詢(xún)),那么只需要加載聚集索引的數(shù)據(jù)頁(yè)即可。 對(duì)于查詢(xún) 2

SELECT s.id, s.name, s.age, sc.subject, sc.score
FROM (SELECT id, name, age FROM student WHERE age > 18) s
LEFT JOIN (SELECT student_id, subject, score FROM score WHERE subject = 'math' AND score > 80) sc 
ON s.id = sc.student_id

連接器:客戶(hù)端與服務(wù)器建立連接。

查詢(xún)緩存:檢查緩存是否存在此查詢(xún)的結(jié)果。如果有,直接返回結(jié)果。否則,繼續(xù)執(zhí)行。

解析器:解析查詢(xún)語(yǔ)句,檢查語(yǔ)法是否正確。

優(yōu)化器:決定使用哪些索引進(jìn)行查詢(xún)優(yōu)化,以及確定連接順序。

執(zhí)行器:開(kāi)始請(qǐng)求執(zhí)行子查詢(xún)。

存儲(chǔ)引擎(InnoDB):首先,對(duì) student 表進(jìn)行掃描,將滿(mǎn)足條件 s.age > 18 的記錄對(duì)應(yīng)的數(shù)據(jù)頁(yè)加載到緩沖池 (如果緩沖池沒(méi)有這個(gè)頁(yè)的數(shù)據(jù))。然后,使用 subject = 'math' AND score > 80 對(duì) score 表進(jìn)行掃描,將滿(mǎn)足條件的記錄對(duì)應(yīng)的數(shù)據(jù)頁(yè)加載到緩沖池 (如果緩沖池沒(méi)有這個(gè)頁(yè)的數(shù)據(jù))。

執(zhí)行器:對(duì)從存儲(chǔ)引擎獲取的數(shù)據(jù)應(yīng)用所有的過(guò)濾條件,過(guò)濾后的結(jié)果存入臨時(shí)表,執(zhí)行主查詢(xún),從臨時(shí)表中獲取數(shù)據(jù),將 s 和 sc 進(jìn)行左連接,根據(jù) s.id = sc.student_id 組合結(jié)果。將連接后的結(jié)果返回給客戶(hù)端。

從這里我們可以看出,查詢(xún) 2 是先過(guò)濾后連接,每張表的索引都很重要,如果沒(méi)設(shè)置好索引,單表過(guò)濾會(huì)全表掃描。 寫(xiě) SQL 的時(shí)候,查詢(xún) 1 和查詢(xún) 2 到底采用哪種方式呢? 根據(jù)不同情況各有應(yīng)用場(chǎng)景,需要注意的是,對(duì)于查詢(xún) 2,子查詢(xún)的結(jié)果集被存儲(chǔ)在一個(gè)臨時(shí)表中,臨時(shí)表不會(huì)繼承原始索引,包括聚集索引和非聚集索引,所以剛剛的例子中,臨時(shí)表中 s.id 和 sc.student_id 已經(jīng)不是任何索引列了。對(duì)于查詢(xún) 1,最終滿(mǎn)足關(guān)聯(lián)條件 s.id = sc.student_id 的所有記錄都會(huì)被加載到內(nèi)存后再進(jìn)行過(guò)濾。

當(dāng)單表過(guò)濾后的數(shù)據(jù)量較小時(shí),查詢(xún) 2 可能是一個(gè)更好的選擇,因?yàn)樗梢詼p少關(guān)聯(lián)操作的數(shù)據(jù)量,從而提高查詢(xún)效率。子查詢(xún)階段,MySQL 依然會(huì)利用原始表上的索引進(jìn)行過(guò)濾。子查詢(xún)執(zhí)行完成后,將過(guò)濾后的數(shù)據(jù)存儲(chǔ)在臨時(shí)表中。所以查詢(xún) 2 的方式可以?xún)?yōu)化的點(diǎn)就是在單表查詢(xún)時(shí)盡可能的利用索引。

當(dāng)單表過(guò)濾后的數(shù)據(jù)量較大時(shí),查詢(xún) 1 可能更合適,因?yàn)樗梢愿玫乩盟饕M(jìn)行關(guān)聯(lián)操作。這樣可以減少關(guān)聯(lián)操作的時(shí)間開(kāi)銷(xiāo),查詢(xún) 2 因?yàn)榕R時(shí)表不繼承索引,表關(guān)聯(lián)的時(shí)間開(kāi)銷(xiāo)比較大。

5. 聚集索引和全表掃描有什么區(qū)別呢?

走PRIMARY 索引(聚集索引)和全表掃描有什么區(qū)別呢?準(zhǔn)確來(lái)說(shuō),使用 InnoDB 存儲(chǔ)引擎的情況下,全表掃描的數(shù)據(jù)和聚集索引的數(shù)據(jù)在 InnoDB 表空間中的存儲(chǔ)位置是相同的,也就是說(shuō)它們的內(nèi)存地址也是相同的。所以你也可以理解為,他們其實(shí)都是在聚集索引上操作的(聚集索引 B + 樹(shù)的葉子結(jié)點(diǎn)是根據(jù)主鍵排好序的完整的用戶(hù)記錄,包含表里的所有字段),區(qū)別就在于 全表掃描將聚集索引 B + 樹(shù)的葉子結(jié)點(diǎn)從左到右依次順序掃描并判斷條件。 聚集索引是利用二分思想將聚集索引 B + 樹(shù)到指定范圍區(qū)間進(jìn)行掃描,比如 select * from demo_info where id in (1, 2) 這種條件字段是主鍵 id,可以很好的利用 PRIMARY 索引進(jìn)行二分的快速查詢(xún)。

在 MyISAM 中,全表掃描的數(shù)據(jù)和索引數(shù)據(jù)的存儲(chǔ)位置是分開(kāi)的。然而 MyISAM 已經(jīng)被 InnoDB 取代,不再是 MySQL 的推薦存儲(chǔ)引擎,從 MySQL5.5 開(kāi)始,InnoDB 就成了 MySQL 的默認(rèn)存儲(chǔ)引擎。 默認(rèn)情況下,InnoDB 使用一個(gè)名為 ibdata1 的共享表空間文件存儲(chǔ)所有的數(shù)據(jù)和索引,包括聚集索引和二級(jí)索引(又稱(chēng)非聚集索引或輔助索引)。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 連接器
    +關(guān)注

    關(guān)注

    99

    文章

    15118

    瀏覽量

    138975
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    780

    瀏覽量

    44737
  • MYSQL數(shù)據(jù)庫(kù)

    關(guān)注

    0

    文章

    96

    瀏覽量

    9712

原文標(biāo)題:一條SQL如何被MySQL架構(gòu)中的各個(gè)組件操作執(zhí)行的?

文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    MySQL執(zhí)行過(guò)程 SQL語(yǔ)句性能優(yōu)化常用策略

    回顧 MySQL執(zhí)行過(guò)程,幫助介紹如何進(jìn)行 sql 優(yōu)化。
    的頭像 發(fā)表于 12-12 10:26 ?850次閱讀
    <b class='flag-5'>MySQL</b>的<b class='flag-5'>執(zhí)行</b>過(guò)程 <b class='flag-5'>SQL</b>語(yǔ)句性能優(yōu)化常用策略

    DRDS分布式SQL引擎—執(zhí)行計(jì)劃介紹

    摘要: 本文著重介紹 DRDS 執(zhí)行計(jì)劃各個(gè)操作符的含義,以便用戶(hù)通過(guò)查詢(xún)計(jì)劃了解 SQL 執(zhí)行
    發(fā)表于 07-12 17:01

    binlog有什么意義/工作模式/優(yōu)缺點(diǎn)

    行數(shù)據(jù)修改的形式,然后在從端對(duì)相同的數(shù)據(jù)進(jìn)行修改  優(yōu)點(diǎn):可以不記錄執(zhí)行SQL語(yǔ)句上下文相關(guān)的信息,只記錄哪一條數(shù)據(jù)修改,修改成什么樣了
    發(fā)表于 01-29 17:24

    在Linux系統(tǒng)下執(zhí)行MySQLSQL文件程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是在Linux系統(tǒng)下執(zhí)行MySQLSQL文件程序免費(fèi)下載。
    發(fā)表于 11-01 17:29 ?4次下載

    select語(yǔ)句和update語(yǔ)句分別是怎么執(zhí)行

    樣,但是具體的實(shí)現(xiàn)還是有區(qū)別的。 當(dāng)然深入了解select和update的具體區(qū)別并不是只為了面試,當(dāng)希望Mysql能夠高效的執(zhí)行的時(shí)候,最好的辦法就是清楚的了解Mysql是如何
    的頭像 發(fā)表于 11-03 09:41 ?3743次閱讀
    select語(yǔ)句和update語(yǔ)句分別是怎么<b class='flag-5'>執(zhí)行</b>的

    一條SQL語(yǔ)句是怎么被執(zhí)行

    直是想知道一條SQL語(yǔ)句是怎么被執(zhí)行的,它執(zhí)行的順序是怎樣的,然后查看總結(jié)各方資料,就有了下面這
    的頭像 發(fā)表于 09-12 09:44 ?1652次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>語(yǔ)句是怎么被<b class='flag-5'>執(zhí)行</b>的

    簡(jiǎn)述SQL更新語(yǔ)句的執(zhí)行流程1

    之前我們講過(guò)了一條SQL查詢(xún)語(yǔ)句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢? 其實(shí)對(duì)于
    的頭像 發(fā)表于 02-14 15:40 ?749次閱讀
    簡(jiǎn)述<b class='flag-5'>SQL</b>更新語(yǔ)句的<b class='flag-5'>執(zhí)行</b>流程1

    簡(jiǎn)述SQL更新語(yǔ)句的執(zhí)行流程2

    之前我們講過(guò)了一條SQL查詢(xún)語(yǔ)句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢? 其實(shí)對(duì)于
    的頭像 發(fā)表于 02-14 15:40 ?658次閱讀
    簡(jiǎn)述<b class='flag-5'>SQL</b>更新語(yǔ)句的<b class='flag-5'>執(zhí)行</b>流程2

    一條SQL查詢(xún)語(yǔ)句是怎么去執(zhí)行的?(上)

    MySQL是典型的`C/S架構(gòu)`(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回
    的頭像 發(fā)表于 03-03 09:58 ?513次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>查詢(xún)語(yǔ)句是怎么去<b class='flag-5'>執(zhí)行</b>的?(上)

    一條SQL查詢(xún)語(yǔ)句是怎么去執(zhí)行的?(

    MySQL是典型的`C/S架構(gòu)`(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回
    的頭像 發(fā)表于 03-03 09:58 ?563次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>查詢(xún)語(yǔ)句是怎么去<b class='flag-5'>執(zhí)行</b>的?(<b class='flag-5'>中</b>)

    一條SQL查詢(xún)語(yǔ)句是怎么去執(zhí)行的?(下)

    MySQL是典型的`C/S架構(gòu)`(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回
    的頭像 發(fā)表于 03-03 09:58 ?518次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>查詢(xún)語(yǔ)句是怎么去<b class='flag-5'>執(zhí)行</b>的?(下)

    mysqlsql server區(qū)別

    MySQLSQL Server是兩種常見(jiàn)的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS),用于存儲(chǔ)和管理數(shù)據(jù)庫(kù)。雖然它們都支持SQL語(yǔ)言,但在其他方面存在些顯著的區(qū)別。以下是
    的頭像 發(fā)表于 11-21 11:07 ?1872次閱讀

    sql where條件的執(zhí)行順序

    。 在深入討論WHERE條件的執(zhí)行順序之前,先回顧一下一SQL語(yǔ)句的執(zhí)行順序。一條SQL語(yǔ)句的
    的頭像 發(fā)表于 11-23 11:31 ?2536次閱讀

    MySQL執(zhí)行過(guò)程:如何進(jìn)行sql 優(yōu)化

    (1)客戶(hù)端發(fā)送一條查詢(xún)語(yǔ)句到服務(wù)器; (2)服務(wù)器先查詢(xún)緩存,如果命中緩存,則立即返回存儲(chǔ)在緩存的數(shù)據(jù); (3)未命中緩存后,MySQL 通過(guò)關(guān)鍵字將 SQL 語(yǔ)句進(jìn)行解析,并生成
    的頭像 發(fā)表于 12-12 10:19 ?583次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>執(zhí)行</b>過(guò)程:如何進(jìn)行<b class='flag-5'>sql</b> 優(yōu)化

    查詢(xún)SQLmysql內(nèi)部是如何執(zhí)行

    我們知道在mySQL客戶(hù)端,輸入一條查詢(xún)SQL,然后看到返回查詢(xún)的結(jié)果。這條查詢(xún)語(yǔ)句在 MySQL 內(nèi)部到底是如何執(zhí)行的呢?本文跟大家探討
    的頭像 發(fā)表于 01-22 14:53 ?732次閱讀
    查詢(xún)<b class='flag-5'>SQL</b>在<b class='flag-5'>mysql</b>內(nèi)部是如何<b class='flag-5'>執(zhí)行</b>?