mySQL子查询慢于2个单独的查询

时间:2014-12-23 13:23:25

标签: mysql sql select subquery query-optimization

我对简单的子查询感到不满。我有以下查询巫婆运行30秒以上:

SELECT DISTINCT SUBSTRING( 6pp, 1, 4 ) AS postcode
FROM 6pp
WHERE gemeenteID
IN (
    SELECT gebiedID
    FROM tmp_orderimport
    WHERE typeGebied = 'Gemeente'
    AND idorder =1733
    AND STATUS = TRUE ); 

说明: Explain

如果我在2个查询中破解查询并首先运行IN部分,整个过程不会超过一秒。但我当然更喜欢使用一个查询。表格在MYISAM中。有什么建议吗?

更新

继Gordon Linoff的榜样之后。我将SQL更改为:

SELECT DISTINCT SUBSTRING( 6pp, 1, 4 ) AS postcode
FROM `6pp`
WHERE EXISTS (SELECT 1
          FROM tmp_orderimport oi
          WHERE oi.gebiedID = `6pp`.gemeenteID AND
                typeGebied = 'Gemeente' AND idorder = 1733 AND STATUS = TRUE
         ); 

并在tmp_orderimport(gebiedID,typeGebied,idorder,status)上添加了一个索引。现在查询运行不到4秒。

新解释: New SQL explain

4 个答案:

答案 0 :(得分:2)

请尝试使用exists

SELECT DISTINCT SUBSTRING( 6pp, 1, 4 ) AS postcode
FROM `6pp`
WHERE EXISTS (SELECT 1
              FROM tmp_orderimport oi
              WHERE oi.gebiedID = `6pp`.gemeenteID AND
                    typeGebied = 'Gemeente' AND idorder = 1733 AND STATUS = TRUE
             ); 

您还可以使用tmp_orderimport(gebiedID, typeGebied, idorder, status)上的索引加快速度。

在将IN与子查询一起使用时,MySQL可能效率低下(有时并且取决于版本)。 EXISTS通常可以解决问题。具体问题是子查询是为每次比较运行的。当您创建临时表时,您可以绕过它。

答案 1 :(得分:1)

使用 INNER JOIN 代替 IN运算符

试试这个:

SELECT DISTINCT SUBSTRING(a.6pp, 1, 4) AS postcode
FROM 6pp a
INNER JOIN tmp_orderimport b ON a.gemeenteID = b.gebiedID 
WHERE b.typeGebied = 'Gemeente' AND b.idorder =1733 AND b.STATUS = TRUE 

答案 2 :(得分:0)

对于主查询的每条记录,MySQL可能运行一次子查询。这最终导致指数处理。

他的子查询独立于主查询,您可以先运行子查询并将值存储在内存中(可能是临时表),然后使用主查询。

答案 3 :(得分:0)

我没有看到有人对你的6pp表发表评论,并且对于(gemeenteID,6pp)有一个索引。我也会在你的tmp_orderimport表上有一个索引(idorder,tpeGebied,status,gebiedID),然后稍微交换一下。

SELECT DISTINCT 
      SUBSTRING( P.6pp, 1, 4 ) AS postcode
   FROM 
      ( SELECT gebiedID
          FROM tmp_orderimport
         WHERE typeGebied = 'Gemeente'
           AND idorder =1733
           AND STATUS = TRUE ) G
      JOIN 6pp P
         on G.gebiedID = P.gemeenteID