【问题标题】:Select speed difference with Subqueries in the FROM Clause在 FROM 子句中选择与子查询的速度差异
【发布时间】:2015-05-30 11:19:46
【问题描述】:

我有一个 IMDB 数据库,我正在尝试计算每年制作的平均演员人数。问题是关于从子查询中选择的速度差异。

我的查询是:

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       |
+-------------+-----------------+-----------------------------------+------------+

造成这种性能差异的原因是什么?有什么办法可以预防?

【问题讨论】:

    标签: mysql database subquery


    【解决方案1】:

    派生:在临时表中扑通一声,没有索引的机会

    子查询:像瘟疫一样避免

    来自https://www.percona.com/blog/2006/08/31/derived-tables-and-views-performance/

    “要注意的是,即使执行 EXPLAIN 语句,派生表也会被物化。因此,如果您在 from 子句中选择错误,即忘记了连接条件,您可能会让 EXPLAIN 永远运行。”

    【讨论】:

    • 我通过CREATE VIEW count_person_per_production AS 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; 创建了一个视图,但它仍在继续派生?
    • 我永远不会使用视图。无论如何,它们是什么?有观点的学者知道的更多,比如拿起指数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多