MySQL选择耗时

时间:2014-11-21 12:50:16

标签: mysql select

我有以下选择查询:

SELECT * FROM mytablename
WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%'))
ORDER BY c5 DESC
LIMIT 0, 25;

此表中有超过2700万行,但有c1c2c3c4的索引。

问题是此查询执行时间超过20分钟。任何想法如何使这更快?

我取出了ORDER BY,它在34秒内完成 - 但是如何使用ORDER BY进行此操作。(c5 DATETIME列是其余的VARCHAR(80)

4 个答案:

答案 0 :(得分:1)

如果查询在没有order by的情况下快速运行,则使用子查询:

SELECT t.*
FROM (SELECT *
      FROM mytablename
      WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%'))
     ) t
ORDER BY c5 DESC
LIMIT 0, 25;

关于表现有一个很大的注意事项。删除order by时,您将获取遇到的前25行。使用order by(在任一查询中),您需要获取整个匹配结果集。无论您使用哪种方法,这都需要更长的时间。

因此,为了具有可比性,您需要在没有order by 的情况下运行查询而不使用limit。这需要多长时间?

答案 1 :(得分:0)

我对此不太确定,请尝试并知道这是否有效:

SELECT * FROM mytablename
WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%'))
and c4 = (SELECT MIN(c4) from mytablename)

答案 2 :(得分:0)

用于获取行的键与ORDER BY中使用的键不同,这可能会降低索引的有用性:

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

通过删除order by语句,您将获取前25个结果,因此这可能不是一个好的基准。

解释声明会有所帮助,但看起来你需要一个包含你使用的所有内容的复合索引。

答案 3 :(得分:0)

您的查询必须选择所有2700万行并检查WHERE,然后对其进行排序,然后只提供前25行。但你确实想要最近的前25个项目。我的经验是,ORLIKE往往会减慢速度,请尝试以下方法:

SELECT * FROM mytablename
WHERE c1 = 'text1' AND 'text2' IN (c2, c3, LEFT(c4, 5))
ORDER BY c5 DESC
LIMIT 0, 25;

编辑 ,因为您更改了c4/c5的错误,c5是否有索引?有助于排序。

如果这仍然太慢,请考虑分区,你真的想查询10年前的项目吗?也许将它们放在不同的分区中。