【问题标题】:Improve performance of subquery in MySQL提高 MySQL 中子查询的性能
【发布时间】:2013-03-25 20:39:15
【问题描述】:

这是我的查询,它使用两个子查询和临时表:

select visit.pid, visit.pidvnum, visit.hpv16, visit.qc_hst
FROM visit,
    (select distinct x.pid  from
        (select pid from visit where visit.qc_hst = 1) x,
        (select pid from visit where visit.hpv16 = 1) y
    where x.pid = y.pid) as subtbl
where visit.pid = subtbl.pid
AND (visit.qc_hst = 1 OR visit.hpv16 =1);

有没有办法重写这个查询来消除一个或两个子查询?我还使用了带有相同两个子查询的 IN 子句,但这更糟。我无法索引像 qc_hst 和 hpv16 这样的字段,因为它们有很多,而且它们中的任何一个都可能成为查询的一部分。

这是一个 sqlfiddle 链接:http://sqlfiddle.com/#!2/68bd6/6/0

非常感谢 - 我真的把头撞到墙上了...

【问题讨论】:

    标签: mysql performance subquery


    【解决方案1】:

    您的查询似乎正在查找 pid 同时满足这两个条件的记录。以下是另一种方法:

    select v.pid, v.pidvnum, v.hpv16, v.qc_hst
    from visit v join
         (select v.pid
          from visit v
          where visit.qc_hst = 1 or visit.hpv16 = 1
          group by pid
          having SUM(v.qc_hst = 1) > 0 and sum(v.hpv16 = 1) > 0
         ) vp
         on v.pid = vp.pid
    where visit.qc_hst = 1 or visit.hpv16 = 1
    

    visit(pid) 上的索引可能会帮助任何查询运行得更快。

    【讨论】:

    • 是的——这两个条件都需要在 pid(它是父键)上满足,而不是在 pidvnum(它是主键)上。您的解决方案看起来不错 - “解释”看起来好多了!但是,它有点“罗嗦”,这会使它在 Java 中的通用编码有点棘手。明天我会告诉你它是如何工作的。
    • 好吧,即使加入更多下游表,它似乎也能很好地工作——这让我很生气。它对我有用!
    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 2023-04-08
    • 2016-08-18
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    相关资源
    最近更新 更多