美文网首页
MySQL子查询性能

MySQL子查询性能

作者: 欧阳_z | 来源:发表于2020-08-25 16:20 被阅读0次

1、语法
子查询有INEXISTS两种,哪种速度更快呢?主要取决于两张表的大小关系。
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<${big};i++));  
do
printf "INSERT INTO \`t_big\` (\`name\`, \`phone\`) VALUES ('zhang%d', '%08d');\n" $[$RANDOM%1000000] $[$RANDOM%100000000] >> second.sql
done

for((i=0;i<${small};i++));  
do
printf "INSERT INTO \`t_small\` (\`name\`, \`nickname\`) VALUES ('zhang%d', '%s');\n" $[$RANDOM%1000000] $(tr -dc "a-z"</dev/urandom|head -c 8) >> second.sql
done
echo "create second.sql success!"

(3)此时大表 t_big 的记录数量多,小表 t_small 的记录少,可以看到使用 EXISTSIN 慢很多。

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)再做一个相反的实验让两个表的位置互换一下,可以看到 EXISTSIN 快。

+----------+------------+------------------------------------------------------------------+
| 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子查询性能

    1、语法子查询有IN和EXISTS两种,哪种速度更快呢?主要取决于两张表的大小关系。SELECT * FROM A...

  • MySQL 子查询、内联结、外联结

    子查询MySQL 子查询版本要求:MySQL4.1引入了对子查询的支持。子查询:嵌套在其他查询语句中的查询。 示例...

  • sql查询优化

    本文来自高性能mysql第6章的总结 问题 我学习mysql的时候,发现了子查询和并列查询结果一样,但是我不知道哪...

  • MySQL 索引及查询优化总结

    本文由云+社区发表 文章《MySQL查询分析》讲述了使用MySQL慢查询和explain命令来定位mysql性能瓶...

  • Day3:MySQL查询基础-查询执行过程

    写在前面为MySQL能够以更高性能执行查询,最优办法是清楚MySQL是如何优化和执行查询。下图展示了MySQL查询...

  • MySQL性能调优

    MYSQL查询语句优化 mysql的性能优化包罗甚广: 索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬...

  • 9月17-MySQL性能优化

    MySQL性能优化策略 1、MySQL内核架构 2、索引原理与查询优化 加速MySQL高效查询数据的数据结构 二分...

  • in子查询陷阱

    对于in子查询性能,众说纷纭。有的人说 in 子查询性能很差,不能使用索引。而有人说 in 子查询能用索引,而且性...

  • 数据库性能优化--引导篇

    MySQL性能标准 QPS:Queries Per Second,每秒查询率。执行查询增加。 TPS:Transa...

  • mysql 查询

    mysql的查询、子查询及连接查询 一、mysql查询的五种子句 where(条件查询)、having(筛选)、g...

网友评论

      本文标题:MySQL子查询性能

      本文链接:https://www.haomeiwen.com/subject/dwjzjktx.html