我有一个 IMDB 数据库,我正在尝试计算每年制作的平均 Actor 人数。问题在于从子查询中选择的速度差异。
我的查询是:
SELECT AVG(sub.num)
FROM
(SELECT
COUNT(production_cast.person_id) AS num,
production.production_year AS pyear
FROM production_cast
INNER JOIN production ON production.id = production_cast.production_id
GROUP BY production.id) sub
GROUP BY(sub.pyear)
但是为了简化起见,以下是问题所涉及的两个查询:
带有子查询
SELECT sub.num
FROM
(SELECT
COUNT(production_cast.person_id) AS num,
production.production_year AS pyear
FROM production_cast
INNER JOIN production ON production.id = production_cast.production_id
GROUP BY production.id) sub
没有子查询:
SELECT
COUNT(production_cast.person_id) AS num,
production.production_year AS pyear
FROM production_cast
INNER JOIN production ON production.id = production_cast.production_id
GROUP BY production.id
第二个的持续时间不到一秒,第一个永远不会完成。 -超过5分钟-。
带有子查询的解释
+-------------+------------------+-------+-----------------------------------+-------------+
| select_type | table | type | key | Extra |
+-------------+------------------+-------+-----------------------------------+-------------+
| PRIMARY | <derived2> | ALL | NULL | NULL |
| DERIVED | production | index | idx_Production_id_production_year | Using index |
| DERIVED | production_cast | ref | production_id | NULL |
+-------------+------------------+-------+-----------------------------------+-------------+
没有子查询的解释:
+-------------+-----------------+-----------------------------------+------------+
| select_type | table | key | Extra |
+-------------+-----------------+-----------------------------------+------------+
| SIMPLE | production | idx_Production_id_production_year | Usingindex |
| SIMPLE | production_cast | production_id | NULL |
+-------------+-----------------+-----------------------------------+------------+
这种性能差异背后的原因是什么?可以采取什么措施来预防它?
最佳答案
派生:在临时表中扑通扑通,没有索引的机会
子查询:像瘟疫一样避免
来自https://www.percona.com/blog/2006/08/31/derived-tables-and-views-performance/
“要注意的是,即使执行 EXPLAIN 语句,派生表也会被具体化。因此,如果您在 select in from 子句中犯了错误,即忘记了联接条件,您可能会永远运行 EXPLAIN。”
关于mysql - FROM 子句中选择与子查询的速度差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30545499/