从子查询中选择id,包含永远占用子查询,而包含子查询的子查询很快

时间:2015-09-23 15:40:10

标签: mysql performance subquery

我有一个查询,子查询和子查询。 (我知道,它不是最美丽的,但这是因为脚本必须从一个激动人心的查询中得到pk)。第一个子查询本身与其他子查询本身运行速度很快。即使它选择了近4000行。但是当我只在它周围添加一个查询以仅选择pk时,它会变成一个怪物查询,它需要花费15分钟来执行。我们把霓虹探测器放在上面,它告诉我们产品/ wincode子查询需要花费太长时间。我们已经看到了它自己,因为当它离开那个时,它很快。 所以它似乎变成了一种循环漏洞。有没有人知道为什么,或者知道一个技巧,找出为什么productwon / wincode子查询在外部查询中花了这么长时间?

SELECT pk FROM
    (SELECT 
        pk,
        responseset_pk,
        responsedate,
        (SELECT product FROM wincode wincodetable  WHERE wincodetable.product != '' AND  wincodetable.code =  
            (
                (SELECT value_text FROM responses ex3
                    WHERE name = 'Wincode'
                    AND (ex3.responseset_pk = ex.responseset_pk)
                )     
            )
        ) AS productwon,

        (SELECT name FROM branch ex2 WHERE ex2.pk = ex.branch_pk) AS branchename

    FROM responses ex
    WHERE responses.question_pk = 1

) t

1 个答案:

答案 0 :(得分:0)

您有一个共同相关的子查询。看看内部子查询如何引用外表的responseset_pk?这意味着必须为从responses表返回的每一行重新运行整个子查询。

通常可以将共同相关的子查询重写为只需要执行一次子查询的连接,尽管该子查询返回所有行的值,这样会更快。您的查询也不例外。

我认为以下内容应该有效。我将子查询更改为连接,并将分支上的子查询替换为简单的连接到分支。

SELECT pk,
    ex.responseset_pk,
    ex.responsedate,
    c.product AS productwon,
    b.name AS branchename
FROM responses ex
join (SELECT responseset_pk, value_text FROM responses WHERE name = 'Wincode') t
    on t.responseset_pk = ex.responseset_pk
join (SELECT code, product FROM wincode wc WHERE wc.product != '') c
    on c.code =  t.value_text
join branch b on b.pk = ex.branch_pk
WHERE responses.question_pk = 1

我不明白为什么你需要外部查询和/或为什么你需要从子查询中选择那些列,如果你在外部查询中忽略它们,那么我就把它关掉了。