我有以下选择查询:
SELECT * FROM mytablename
WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%'))
ORDER BY c5 DESC
LIMIT 0, 25;
此表中有超过2700万行,但有c1
,c2
,c3
和c4
的索引。
问题是此查询执行时间超过20分钟。任何想法如何使这更快?
我取出了ORDER BY,它在34秒内完成 - 但是如何使用ORDER BY进行此操作。(c5
DATETIME
列是其余的VARCHAR(80)
)
答案 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个项目。我的经验是,OR
和LIKE
往往会减慢速度,请尝试以下方法:
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年前的项目吗?也许将它们放在不同的分区中。