成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文帶你了解MySQL是如何優(yōu)化in子查詢的,其實非常簡單

數(shù)據(jù)庫 MySQL
今天就帶大家了解一下,MySQL到底是怎么來優(yōu)化in子查詢的。

對于很多的開發(fā)小伙伴來說,在MySQL中進行in子查詢是一個非常常見的操作。

雖然也有很多人說,盡量少用in子查詢,in的數(shù)量過多會影響查詢性能。

但其實MySQL做了不少的優(yōu)化手段來保證in子查詢的性能,大家也能在實際的業(yè)務中感受到in子查詢的速度也沒那么慢。

那今天就帶大家了解一下,MySQL到底是怎么來優(yōu)化in子查詢的。

普通in子查詢

首先,我們看一下MySQL是如何執(zhí)行一個普通的in子查詢的。

以一個簡單的子查詢?yōu)槔?/p>

select  * from table1 where key1 in ('bb','ff','gg');

對于這個子查詢畫了一個簡單的查詢圖,不同顏色代表不同的數(shù)據(jù)頁。

在這個圖里,最上層的是根節(jié)點,中間的是非葉子節(jié)點,最下面的是葉子節(jié)點。

對于一個普通的二級索引來說,葉子節(jié)點存儲的是索引key和主鍵id,這些基礎知識就不詳細展開說了。

需要注意的是,二級索引在葉子節(jié)點中是按照key的順序從小到大排序的,但是對應的主鍵id可不一定。

可能與大家想象的不同,MySQL在執(zhí)行in子查詢時,會把in語句中的條件當做一個個的區(qū)間,比如:

['bb','bb'],['ff','ff'],['gg','gg']

然后MySQL在二級索引樹上,會先查詢['bb','bb']這個區(qū)間,比如首先查詢到第一個數(shù)據(jù)頁中符合條件的第一條數(shù)據(jù)(bb,2),獲取到主鍵id=2之后,去聚簇索引回表查詢所需的數(shù)據(jù)(因為我們使用的select *,需要獲取到所有的列值)。

然后查詢第一個數(shù)據(jù)頁中符合條件的第二條數(shù)據(jù)(bb,5),獲取到主鍵id=5之后,去聚簇索引回表查詢所需的數(shù)據(jù),

然后查詢第二個數(shù)據(jù)頁中符合條件的第三條數(shù)據(jù)(ff,6),

不斷的重復上面的動作。。。。

最后獲取到一個結果集,返回到Server,再由Server返回到客戶端。

看到這里大家是否可以感覺到,這樣查詢數(shù)據(jù)也太麻煩了,特別是當in子查詢的條件越來越多時,如何保證性能呢?

下面,我們一起來看一下,MySQL是如何優(yōu)化in子查詢的。

物化表

首先,為了演示我們建兩張表table1和table2,并建立兩個二級索引idx_c1和idx_c2。

CREATE TABLE table1  (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_c1`(`c1`) USING BTREE
) ENGINE = InnoDB

CREATE TABLE table2 (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c2` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_c2`(`c2`) USING BTREE
) ENGINE = InnoDB

下面以一個簡單的子查詢?yōu)槔涸趖able2表中查詢t2.c2=3的id,并作為table1表c1的查詢條件。

SELECT
*
FROM
table1 t1
WHERE
t1.c1 IN ( SELECT id FROM table2 t2 WHERE t2.c2 = 3 );

對于一個這樣普通的子查詢來說,MySQL使用了一種叫做物化表的方式來提升性能。

什么意思呢?

就是將子查詢的結果集去重后放入到一個臨時表中,臨時表的列就是子查詢的結果集中的列。

去重的目的是為了讓臨時表盡可能的精簡,因為在臨時表中重復的列并沒有什么意義。

當結果集比較小時,MySQL會為臨時表使用memory引擎,并且為臨時表中的列建立哈希索引。哈希索引的查詢時間復雜度是O(1),查詢速度是非常快的。

但是如果結果集比較大時,MySQL就會將臨時表定義為InnoDB類型表,并且建立B+樹索引,就像一個普通的表一樣使用。

話說回來,將子查詢轉換為臨時表以后,其實查詢就變成了兩張表的連接查詢,也就是兩個表的內連接。

一旦轉換為內連接就好辦了,經典的“小表驅動大表”的優(yōu)化準則就可以派上用場了。

我們看一下MySQL優(yōu)化器對上面的SQL優(yōu)化后的結果:

SELECT
`t1`.`id` AS `id`,
`t1`.`c1` AS `c1`
FROM
`table2` `t2`
JOIN `table1` `t1`
WHERE
( ( `t1`.`c1` = `t2`.`id` ) AND ( `t2`.`c2` = 3 ) )

可以看到,MySQL將其轉換為了內連接,并且以table2為驅動表,table1為被驅動表的方式進行了查詢。

由于c1和c2列上都有索引,那么此時這個sql的執(zhí)行速度還是相當可以的。

半連接

雖然通過物化表的方式,MySQL將子查詢轉換為了連接查詢,但是創(chuàng)建臨時表的成本也是有的。

那可不可以再優(yōu)化一步,將創(chuàng)建臨時表的成本也給優(yōu)化掉呢?

在某些情況下,確實是可以的。

在上文我們提到,MySQL會將子查詢的結果集去重后,放入一個臨時表中。

那大家是否意識到,這個臨時表中的記錄都是唯一的,換句話說,就是一個唯一索引的列。

那么當我們的子查詢語句的結果集也類似于一個唯一索引集時,MySQL就不去創(chuàng)建臨時表了,而是直接嘗試將sql改寫成內連接。

半連接的優(yōu)化還是比較復雜的,要求條件相對也苛刻一點,這里就不再詳細的說了,感興趣的朋友可以去深入學習一下。

最后

無論MySQL采用了哪種優(yōu)化方法,只要知道了其實現(xiàn)的大致原理,對于使用者來說,就有了對應的優(yōu)化思路。

特別建議大家寫完SQL以后,習慣性的使用explain分析一下是否命中了索引,掃描的行數(shù)是否過多。

只有不斷的實操,優(yōu)化SQL的能力才會不斷提升。

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-03-31 08:16:53

Flutter優(yōu)化內存管理

2022-09-29 13:09:38

DataClassPython代碼

2025-01-15 09:06:57

servlet服務器Java

2023-11-06 08:16:19

APM系統(tǒng)運維

2022-11-11 19:09:13

架構

2023-11-20 08:18:49

Netty服務器

2023-05-17 11:33:45

梯度下降機器學習

2022-03-14 08:01:06

LRU算法線程池

2018-10-22 08:14:04

2019-07-04 15:16:52

數(shù)據(jù)挖掘大數(shù)據(jù)算法

2022-09-06 11:21:49

光網絡光纖

2021-02-06 13:45:59

SQL子查詢數(shù)據(jù)庫

2023-10-27 08:15:45

2022-02-24 07:34:10

SSL協(xié)議加密

2023-11-08 08:15:48

服務監(jiān)控Zipkin

2019-04-19 14:03:52

APISDK接口

2023-04-11 08:01:32

Web 開發(fā)源代碼映射

2022-02-15 08:38:04

錯誤邏輯異常編程程序

2024-02-04 09:44:41

量子計算量子量子物理

2022-04-28 09:22:46

Vue灰度發(fā)布代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品av麻豆的观看方式 | 毛片在线免费 | 亚州影院| 欧美中文字幕一区二区三区亚洲 | 国产精品99久久久久 | 亚洲精品一区二区 | 欧美一区二区在线播放 | www.婷婷亚洲基地 | 成人区精品一区二区婷婷 | 精品久久影院 | 亚洲一区二区三区在线 | 国产亚洲欧美日韩精品一区二区三区 | 成人二区| 国产精品美女久久久久aⅴ国产馆 | 人人做人人澡人人爽欧美 | 一区中文字幕 | 日韩成人在线视频 | 超碰在线人人 | 日韩欧美日韩在线 | 欧美日韩一区二区三区四区五区 | 亚洲中午字幕 | 超碰在线人人干 | 网站黄色在线免费观看 | 国产成人精品亚洲日本在线观看 | 成人欧美 | 国产高清视频在线播放 | 欧美炮房 | 精品日韩一区二区三区av动图 | 欧美亚洲一区二区三区 | 国产小视频在线 | 91在线精品一区二区 | 成人免费一区二区三区视频网站 | 欧美9999| 亚洲第一区国产精品 | 色爱区综合 | 欧美精品1区2区 | 中文字幕韩在线第一页 | 国产成在线观看免费视频 | 老司机精品福利视频 | 国产日韩精品在线 | 在线观看深夜视频 |