mysql子查詢效能 MySQL子查詢效能

2021-10-18 15:33:28 字數 2590 閱讀 3792

1、語法

子查詢有in和exists兩種,哪種速度更快呢?主要取決於兩張表的大小關係。

select * from a where cc in (select cc from b);

select * from a where exists (select cc from b where b.cc=a.cc);

in會先查詢b,然後把查詢b的結果,做為輸入,再查詢a,當 a 記錄多時,可以很好的利用 a 的索引,時間複雜度是o(b*log a)。

exists會先查詢a,然後把查詢a的結果,做為輸入,再查詢b,當 b 記錄多時,可以很好的利用 b 的索引,時間複雜度是o(a*log b)。

2、下面來做個實驗

(1)先執行 source first.sql; 來建立 2 張資料表

drop table if exists `t_big`;

create table `t_big` (

`id` int(11) not null auto_increment,

`name` varchar(30) not null,

`phone` varchar(30) not null,

primary key (`id`),

key idx_name(`name`),

key idx_phone(`phone`)

) engine = innodb;

drop table if exists `t_small`;

create table `t_small` (

`id` int(11) not null auto_increment,

`name` varchar(30) not null,

`nickname` varchar(30) not null,

primary key (`id`),

key idx_name(`name`),

key idx_nickname(`nickname`)

) engine = innodb;

(2)執行如下 shell 指令碼bash rand.sh來生成隨機資料的 sql 插入語句的 second.sql 檔案,再執行 source second.sql; 來插入資料:

#!/bin/bash

small=50

big=500000

rm -f second.sql

for((i=0;i

doprintf "insert into \`t_big\` (\`name\`, \`phone\`) values ('zhang%d', '%08d');\n" $[$random%1000000] $[$random%100000000] >> second.sql

done

for((i=0;i

doprintf "insert into \`t_small\` (\`name\`, \`nickname\`) values ('zhang%d', '%s');\n" $[$random%1000000] $(tr -dc "a-z"> second.sql

done

echo "create second.sql success!"

(3)此時大表 t_big 的記錄數量多,小表 t_small 的記錄少,可以看到使用 exists比 in 慢很多。

mysql> set profiling = 1;

select * from t_big where `name` in (select `name` from t_small);

mysql> show profiles;

| query_id | duration | query |

| 1 | 0.01406125 | select * from t_big where `name` in (select `name` from t_small) |

| query_id | duration | query |

| 1 | 1.65336600 | select * from t_big where exists (select `name` from t_small where t_big.name=t_small.name) |

(4)再做乙個相反的實驗讓兩個表的位置互換一下,可以看到 exists 比 in 快。

| query_id | duration | query |

| 1 | 0.00277950 | select * from t_small where `name` in (select `name` from t_big) |

| query_id | duration | query |

| 1 | 0.00050700 | select * from t_small where exists (select `name` from t_big where t_small.name=t_big.name) |

3、結論

當 a > b,用 in:

select * from a where cc in (select cc from b);

當 a < b,用 exists:

select * from a where exists (select cc from b where b.cc=a.cc);

mysql查詢效能優化 MySQL 查詢效能優化

在日常開發中,程式設計師寫的最多的除了bug之外,應該算是sql語句了。sql的質量影響了程式的響應速度,只有利用mysql的特性,才能讓mysql更有效的執行查詢sql,充分發揮mysql的優勢,並避開它的弱點。為什麼查詢速度會慢?在編寫sql之前,需要清楚一點 真正重要的是響應時間。如果我們把查...

mysql求和 子查詢 MySQL子查詢

到現在為止,我們已經表明,以select宣告是乙個簡單的查詢。該單個語句從單個資料庫表中檢索資料。sql還同意建立乙個子查詢。即巢狀在其他查詢的查詢。下列實施例給出巢狀查詢。一種表示訂單資訊儲存,包含訂單號,客戶id。訂購日期。例如以下所看到的 一張表示儲存訂單物品資訊,例如以下 另一張表儲存的是客...

mysql子查詢應用案例 MySQL子查詢

mysql子查詢 子查詢 sub query,查詢是在某個查詢結果之上進行的,一條select語句內部包含了另外一條select語句。分類子查詢有兩種分類方式,分別為 按按結果分類和位置分類。按結果分類,即根據子查詢得到的資料進行分類 理論上,任何乙個查詢結果都可以理解為乙個二維表 分別為 標量子查...