【问题标题】:Increase speed of SQL query execution提高 SQL 查询执行速度
【发布时间】:2014-03-28 10:49:49
【问题描述】:

我有这个在 java 中通过 JDO 运行的 SQL 查询:

SELECT idPath, token, isTV, rel
FROM path
LEFT OUTER JOIN relation ON (path.idTokenN=relation.idTokenN)
WHERE path.idPath IN( SELECT DISTINCT path.idPath
                      FROM path
                      WHERE path.isTV='true'
                    )
  AND path.idPath IN( SELECT DISTINCT path.idPath
                      FROM path
                      GROUP BY path.idPath
                      HAVING COUNT(*) >= 2 AND COUNT(*) <= 3
                    )

运行大约需要 3 个小时,如何减少执行时间?

编辑

使用 MySQL DBMS

路径表:

     idTokenN idPath  token      isTV
       1      p1      test1      true
       2      p1      test2      false
       3      p2      test3      true
       4      p3      test4      false
       5      p3      test5      false
       6      p4      test6      false
       7      p4      test7      true
       8      p4      test8      false
       9      p4      test9      false
       10     p5      test10     true
       11     p5      test11     false
       12     p5      test12     false

关系表:

      idTokenN  idTokenN2  rel
       10       11         test

当然我的数据库中的数据很多,这只是一个例子!

【问题讨论】:

  • 您对用于过滤的列有索引吗?表中的数据大小是多少?
  • IN (...) 子句是这里最可能出现的问题。通常,这些可以用连接更有效地替换。但是您必须向我们提供有关数据和您要完成的实际任务的更多信息。还有你正在使用的数据库。
  • 请提供执行计划和您在表中定义的索引。并告诉我们您使用的是哪个 DBMS(Postgres、Oracle 等)?
  • 我已经更新了问题!我想我已经添加了所有内容!

标签: java sql jdo


【解决方案1】:

优化查询取决于几个因素。最重要的是数据库引擎。二是数据的特点。您的问题没有提供关于这两个方面的信息。

一个非常重要的信息是两个表的大小、每个表中的行数以及每个表中idTokenN 的不同值的数量。 left outer join 很有可能决定了查询的性能特征。

您可以做的第一件事是删除distinct 关键字。这在in 子查询中是不需要的,一些数据库引擎可能不会忽略它。

优化查询的另一个步骤是删除in 子查询。在某些数据库中,这些优化得不好。它们可以替换为join 和聚合子查询:

SELECT p.idPath, p.token, p.isTV, r.rel
FROM path p LEFT OUTER JOIN
     relation r
     ON p.idTokenN = r.idTokenN JOIN
     (select idPath, max(case when p.isTV = 'true' then 1 else 0 end) as HasTv,
             (case when COUNT(*) between 2 and 3 then 1 else 0 end) as Has2_3
      from path p
      group by idpath
     ) pf
     on p.idpath = pf.idpath and
        pf.HasTv = 1 and pf.Has2_3  = 1;

您当然可以做其他事情,但除此之外,它们变得依赖于数据库。

【讨论】:

    猜你喜欢
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    相关资源
    最近更新 更多