1

我有许多类似的电话。下面是一个:

$STH = $DBH->prepare("
SELECT t.mobile, t.unum
FROM teacher t
LEFT JOIN s_group_member m ON m.unum = t.unum
LEFT JOIN s_group g ON g.gnum = m.gnum
WHERE m.gnum = :g AND g.unum = :u
  AND t.unum NOT IN (SELECT unum FROM t_unav WHERE unav_date = :d)");

它从teacher表中获取数据,其中 (1) 教师是指定组的成员,(2) 该组属于用户,以及 (3) 教师不可用。

我的问题是最快的:

  1. 每次都进行子选择调用。
  2. 将子选择缓存到一个数组中,然后像在这篇文章中一样使用 IN($array) 。
  3. 创建一个临时表。

类似的电话被打了好几次——也许是 20 到 30 次……

谢谢。

4

1 回答 1

2

您示例中的子查询应该是MATERIALIZED,这意味着它将只执行一次(mysql 将自动创建一个 tmp 表来存储子查询的结果)。

使用临时表的子查询实现避免了这种重写,并且可以只执行一次子查询,而不是每行外部查询一次。物化通过将子查询结果生成为临时表(通常在内存中)来加速查询执行。MySQL 第一次需要子查询结果时,会将结果具体化到一个临时表中。任何后续需要结果时,MySQL 都会再次引用临时表。

但是,如果子查询的结果不大,您确实可以将它们放入数组中,它应该会快一点。

您也可以在这里EXISTS查看优化

于 2013-06-21T07:04:57.590 回答