我遇到这个运行时间超过10秒的慢查询的问题:
SELECT DISTINCT siteid,
storyid,
added,
title,
subscore1,
subscore2,
subscore3,
( 1 * subscore1 + 0.8 * subscore2 + 0.1 * subscore3 ) AS score
FROM articles
WHERE added > '2011-10-23 09:10:19'
AND ( articles.feedid IN (SELECT userfeeds.siteid
FROM userfeeds
WHERE userfeeds.userid = '1234')
OR ( articles.title REGEXP '[[:<:]]keyword1[[:>:]]' = 1
OR articles.title REGEXP '[[:<:]]keyword2[[:>:]]' = 1 ) )
ORDER BY score DESC
LIMIT 0, 25
根据用户添加到其帐户的网站输出故事列表。排名由分数确定,分数由子分数列组成。
查询使用filesort并在PRIMARY和feedid上使用索引。 EXPLAIN的结果:
1 PRIMARY articles
range
PRIMARY,added,storyid
PRIMARY 729263 rows
Using where; Using filesort
2 DEPENDENT SUBQUERY
userfeeds
index_subquery storyid,userid,siteid_storyid
siteid func
1 row
Using where
有任何改进此查询的建议吗?谢谢。
答案 0 :(得分:0)
我会将计算逻辑移到客户端,只加载数据库中的字段。这使您的查询和计算本身更快。在SQL代码中执行此类操作并不是一种好的方式。 并且正则表达式非常慢,也许像“LIKE”这样的另一种搜索模式更快。</ p>
答案 1 :(得分:0)
查看您的EXPLAIN
,您的查询似乎没有使用任何索引(因此是filesort)。这是由计算列(score
)上的排序引起的。
另一个障碍是桌子的大小(729263行)。您不希望创建一个太宽的索引,因为它会占用更多空间并影响CUD操作的性能。我们想要做的是定位正在选择的列,但是,在这种情况下我们不能,因为它是一个计算列。您可以尝试创建VIEW
或删除排序或在应用程序层执行此操作。