如果我在 where 子句中应用静态数据,那么应用子查询会更快。例子:
(查询返回5条记录作为结果集)
SELECT STARTDATE, ENDDATE FROM TEST WHERE STARTDATE = '2012-08-21';
然后更快:
SELECT STARTDATE, ENDDATE FROM TEST WHERE STARTDATE = (SELECT STARTDATE FROM TEST2 LIMIT 1);
或者它们在任何情况下都是相同的?
子查询是在每次比较时对每条记录按查询执行还是仅执行 1 次?
在 MySQL 5.6 之前,内部查询对外部行中的每个条目执行一次,并且很容易证明:
mysql> SELECT COUNT(*) FROM sample_data;
+----------+
| COUNT(*) |
+----------+
| 8 |
+----------+
1 row in set (0.00 sec)
mysql> SELECT COUNT(*) FROM sample_data WHERE id = (SELECT SLEEP(1) );
+----------+
| COUNT(*) |
+----------+
| 0 |
+----------+
1 row in set (8.00 sec)
Run Code Online (Sandbox Code Playgroud)
请注意,查询需要 8 秒,因此 SLEEP(1) 执行 8 次,对 中的每一行执行一次sample_data
。
MySQL 5.6 已经实现了子查询物化,理论上可以防止这种情况在很多情况下发生。MariaDB 也有一个大大改进的优化器,可以防止这种情况。
在大多数情况下,最好避免 MySQL 中的子查询。
正如 Aaron 所说,MySQL 优化器有时很愚蠢。如果您没有使用 MariaDB 最新版本(并且您不能等待 MySQL 5.6 发布),您仍然可以“欺骗”优化器运行一次子查询,方法是将其从WHERE
toFROM
子句中移出:
SELECT t.STARTDATE, t.ENDDATE
FROM
TEST AS t
JOIN
(SELECT STARTDATE FROM TEST2 LIMIT 1) AS s
ON t.STARTDATE = s.STARTDATE ;
Run Code Online (Sandbox Code Playgroud)