如何优化MySQL查询

时间:2012-03-30 14:28:02

标签: mysql sql optimization query-optimization

给出以下表格结构

images                 data
 ------------------    ----------------------------------
| id    | filename |  | fromImageId | toImageId | result |
 ------------------    ----------------------------------

我有以下SELECT来获取images.filename中没有条目的所有datafromImageIdtoImageId

SELECT image.id, image.filename
FROM images image
WHERE NOT EXISTS(
    SELECT fromImageId, toImageId
    FROM data results
    WHERE fromImageId = image.id
        OR toImageId = image.id
) ORDER BY image.id

由于data表非常大(500,000+),因此查询需要很长时间才能计算(大约10-15秒)。

我非常确定这里有很多优化要做,但我无法理解我可以做些什么来优化查询。

PS:images.idPRIMARY KEYfromImageIdtoImageId FOREIGN KEY上的images.id

4 个答案:

答案 0 :(得分:4)

SELECT
    images.id,
    filename
FROM
    images
LEFT JOIN `data` ON images.id = fromImageId
OR images.id = toImageId
WHERE
    fromImageId IS NULL AND toImageId IS NULL

确保索引位于fromImageIdtoImageId

答案 1 :(得分:2)

确保您的“数据”表至少包含两个索引...一个只有FROM图像ID,另一个只有To Image ID。然后,与迈克尔提出的建议略有不同

select STRAIGHT_JOIN
      i.ID,
      i.FileName
   from
      Images i
         LEFT JOIN Data d1
            on i.ID = d1.FromImageID
         LEFT JOIN Data d2
            on i.ID = d2.ToImageID
   where
          d1.FromImageID is null
      AND d2.ToImageID is null

使用两个单独的索引,此查询从您的图像文件开始,并与您的数据表的两个版本对齐...分别由EITHER加入或同时加入图像值。所以现在,它应该只是吹嘘并且只开出那些“数据”表没有找到匹配的条目。

答案 2 :(得分:0)

NOT IN可能是更好的选择。没有测试过,但请尝试以下

SELECT image.id, image.filename
FROM images image
WHERE image.id NOT IN(
    SELECT IFNULL(fromImageId, toImageId)
    FROM data results
    WHERE fromImageId = image.id
        OR toImageId = image.id
) ORDER BY image.id

答案 3 :(得分:0)

我可以考虑形成这个查询的另一种方法是:

SELECT image.id, image.filename
FROM images image
WHERE image.id NOT IN(
    SELECT fromImageId, toImageId
    FROM data results
) ORDER BY image.id

不知道它会做什么“优化”,但也许您应该考虑将其设为存储过程