子查询为父查询执行 1 次还是更多?

Sat*_*dey 4 mysql select

如果我在 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 次?

Aar*_*own 8

在 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 中的子查询。


ype*_*eᵀᴹ 5

正如 Aaron 所说,MySQL 优化器有时很愚蠢。如果您没有使用 MariaDB 最新版本(并且您不能等待 MySQL 5.6 发布),您仍然可以“欺骗”优化器运行一次子查询,方法是将其从WHEREtoFROM子句中移出:

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)