两个查询分别快速,而作为子查询联接时则较慢

如何解决两个查询分别快速,而作为子查询联接时则较慢

| 我有两个查询,每个查询都运行得非常快(不到2秒)。但是,当我尝试将它们作为子查询加入时,它运行起来非常缓慢。我上次跑步大约花了68秒。这是完整的查询
SELECT t.count,t.total
  FROM (SELECT t.account_number,COUNT(t.id) count,SUM(t.amount) total,ib.id import_bundle_id
          FROM import_bundle ib
          JOIN generic_import gi ON gi.import_bundle_id = ib.id
          JOIN transaction_import ti ON ti.generic_import_id = gi.id
          JOIN account_transaction t ON t.transaction_import_id = ti.id
          JOIN transaction_code tc ON t.transaction_code_id = tc.id
         WHERE tc.code IN (0,20,40)
      GROUP BY t.account_number) t
  JOIN (SELECT a.account_number,np.code
          FROM import_bundle ib
          JOIN generic_import gi ON gi.import_bundle_id = ib.id
          JOIN account_import ai ON ai.generic_import_id = gi.id
          JOIN account a ON a.account_import_id = ai.id
          JOIN account_northway_product anp ON anp.account_id = a.id
          JOIN northway_product np ON anp.northway_product_id = np.id
         WHERE np.code != \'O1\') a ON t.account_number = a.account_number
查询应缓慢运行并不令人意外。如果这些是两个单独的表而不是子查询,则将索引放在它们的“ 1”列上。但是,显然不可能在查询结果上放置索引,所以我不能这样做。我怀疑这是问题的一部分。 除此之外,除了添加两个汇总表(我不愿意这样做)之外,我不理解查询为什么会变慢并且对如何加快查询没有任何想法不必。 顺便说一句,此查询的英文内容可能是“为不是透支保护帐户的帐户(代码O1)获取所有POS交易(代码0、20和40)。”

解决方法

将支票放入主查询中:
SELECT  t.account_number,COUNT(t.id) count,SUM(t.amount) total,ib.id import_bundle_id
FROM    transaction_code tc
JOIN    account_transaction t
ON      t.transaction_code_id = tc.id
JOIN    transaction_import ti
ON      ti.id = t.transaction_import_id
JOIN    generic_import gi
ON      gi.id = ti.generic_import_id
JOIN    import_bundle ib
ON      ib.id = gi.import_bundle_id
WHERE   tc.code IN (0,20,40)
        AND t.account_number NOT IN
        (
        SELECT  anp.id
        FROM    account_northway_product anp
        JOIN    northway_product np
        ON      np.id = anp.northway_product_id
        WHERE   np.code = \'01\'
        )
GROUP BY
        t.account_number
创建以下索引:
transaction_code (code)
account_transaction (transaction_code_id)
account_transaction (account_number)
,根据我从您看到的查询; 1)好像您的PK是import_bundle表上的帐号。您需要在该列上聚集索引 2)在(代码)northway_product表和(代码)transaction_code表上添加索引也会有所帮助。,由于整体复杂性,MySQL可能错误地优化了查询。 您可能会发现最好的选择是分阶段运行它。
SELECT * INTO #query1 FROM <query1>
SELECT * INTO #query2 FROM <query2>
SELECT * FROM #query1 INNER JOIN #query2 ON <predicate>
另一种选择是使用HINTS,尽管我对MySQL不熟悉。本质上,找出分别为每个子查询生成的计划,然后强制不同的联接使用NESTED LOOP JOIN,MERGE JOIN等。这限制了优化器可以执行的操作,因此得到“错误”,但也限制了它。的能力随着数据统计信息的变化而变化。,由于您的大多数表已经被联接,为什么要再次联接...只需附加已经设置了ID的其他表即可。此外,由于所有都是JOIN且都不是LEFT联接,因此隐含仅获取在所有联接中找到的记录(因为原始查询最终也将联接结果集)。 另外,通过添加AND np.code!= \ '01 \',它将立即排除那些条目,因此仅保留查询中所需的那些条目。因此,此内部\“ PreQuery \”(别名为PQ)可以为您完成所有工作。但是,您的group by不包含导入捆绑包ID,并且对您的错误回答可能是MAY。根据需要进行调整。然后,结果只是拉出两列...计数和总计将返回多行,但没有帐户或总计的上下文,但是您可以根据需要进行调整。
SELECT PQ.count,PQ.total
  FROM (SELECT STRAIGHT_JOIN
            t.account_number,ib.id import_bundle_Id
         FROM 
            transaction_code tc
               join account_transaction t
                  on tc.id = t.transaction_import_id
               join transaction_import ti
                  on t.transaction_import_id = ti.id
               join generic_import gi
                  on ti.generic_import_id = gi.id
               join import_bundle ib
                  on gi.import_bundle_id = ib.id
               join account_import ai 
                  on gi.id = ai.generic_import_id
               join account a
                  on ai.id = a.account_import_id
               join account_northway_product anp
                  on a.id = anp.account_id
               join northway_product np
                  on anp.northway_product_id = np.id
                  AND np.code != \'01\'
         where
            tc.code in ( 0,40 )
         group by 
            t.account_number ) PQ

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?