谁能解释一下为什么这些查询的执行时间不同?

问题描述 投票:0回答:1

我需要得到8个子查询,但它们只作为一个查询运行正常,当只使用其中一个作为子查询时,执行时间从4秒到4分钟,对于同样的查询,我需要另外7个子查询,多了60倍的时间。

SELECT
    SUBSTR(benches.name, 1, 2) as Bancada,
    /* USUARIOS - HOMBRES */
    (
    SELECT COUNT(DISTINCT SubUser.document) AS '01'
        FROM loan_historical as SubLoan
             LEFT JOIN anchors as SubLoanAnchor ON SubLoanAnchor.uuid = SubLoan.loan_anchor_uuid
             LEFT JOIN benches as SubLoanBench ON SubLoanBench.uuid = SubLoanAnchor.bench_uuid
             LEFT JOIN users AS SubUser ON (SubUser.change_uuid = (
                 SELECT change_uuid FROM users WHERE uuid = SubLoan.use_uuid ORDER BY users.date_change DESC LIMIT 1
             ))
             LEFT JOIN login_cards AS SubLoginCards ON (SubLoginCards.uuid = (
                 SELECT uuid FROM login_cards WHERE use_uuid = SubLoan.use_uuid ORDER BY login_cards.date_created DESC LIMIT 1
             ))
        WHERE SubLoan.use_uuid IS NOT NULL
             AND (SubLoginCards.worker = 0 OR SubLoginCards.worker IS NULL)
             AND YEAR(SubLoan.loan_date_created) = 2019
             AND MONTH(SubLoan.loan_date_created) = 1
             AND SubLoan.use_uuid IS NOT NULL
             AND SubUser.gender = 'M'
             AND SUBSTR(SubLoanBench.name, 1, 2) = Bancada
             AND TIMESTAMPDIFF(YEAR, SubUser.birthday, '2019-01-01') < 18
        ORDER BY SubUser.document ASC) AS 'UM0017'
FROM benches
ORDER BY benches.name;

这是第二个查询,工作正常。

SELECT COUNT(DISTINCT SubUser.document) AS '01'
FROM loan_historical as SubLoan
     LEFT JOIN anchors as SubLoanAnchor ON SubLoanAnchor.uuid = SubLoan.loan_anchor_uuid
     LEFT JOIN benches as SubLoanBench ON SubLoanBench.uuid = SubLoanAnchor.bench_uuid
     LEFT JOIN users AS SubUser ON (SubUser.change_uuid = (
         SELECT change_uuid FROM users WHERE uuid = SubLoan.use_uuid ORDER BY users.date_change DESC LIMIT 1
     ))
     LEFT JOIN login_cards AS SubLoginCards ON (SubLoginCards.uuid = (
         SELECT uuid FROM login_cards WHERE use_uuid = SubLoan.use_uuid ORDER BY login_cards.date_created DESC LIMIT 1
     ))
WHERE SubLoan.use_uuid IS NOT NULL
     AND (SubLoginCards.worker = 0 OR SubLoginCards.worker IS NULL)
     AND YEAR(SubLoan.loan_date_created) = 2019
     AND MONTH(SubLoan.loan_date_created) = 1
     AND SubLoan.use_uuid IS NOT NULL
     AND SubUser.gender = 'M'
     AND SUBSTR(SubLoanBench.name, 1, 2) = '01'
     AND TIMESTAMPDIFF(YEAR, SubUser.birthday, '2019-01-01') < 18
ORDER BY SubUser.document ASC;
mysql query-performance delayed-execution
1个回答
1
投票
  • 不要使用 LEFT JOINJOIN 是你所需要的。 特别是对于 SubUser.
  • 把change_uuid的子查询移出一层。 其他子查询也是如此。
  • 使用日期比较,而不是提取DIFF, YEAR, MONTH。
  • 换成 AND SubLoanBench.name LIKE '01%'. 您可以使用 CONCAT 来动态构造LIKE`的目标,但运行速度可能较慢。
  • SubLoan.use_uuid IS NOT NULL 出现两次。
  • 如果你有一个巨大的表,UUID本身效率就很低。
  • (SubLoginCards.worker = 0 OR SubLoginCards.worker IS NULL ) 不能使用索引,可以考虑使用 0NULL,但不能同时使用。 这样,这个表达式就可以简化了。
  • ORDER BY 是不相关的,因为只有一行(与 COUNT).
  • 如果所有的子查询都是相似的,那么它 在一次查询中就能完成所有的查询,并能通过一个 GROUP BY?

在你解决了一些问题后,我再来看看最佳指数。 同时,请提供 SHOW CREATE TABLE.

© www.soinside.com 2019 - 2024. All rights reserved.