使用AS和子查询减慢MySQL查询

时间:2012-10-22 13:55:48

标签: mysql database performance optimization subquery

我遇到这个运行时间超过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

有任何改进此查询的建议吗?谢谢。

2 个答案:

答案 0 :(得分:0)

我会将计算逻辑移到客户端,只加载数据库中的字段。这使您的查询和计算本身更快。在SQL代码中执行此类操作并不是一种好的方式。 并且正则表达式非常慢,也许像“LIKE”这样的另一种搜索模式更快。<​​/ p>

答案 1 :(得分:0)

查看您的EXPLAIN,您的查询似乎没有使用任何索引(因此是filesort)。这是由计算列(score)上的排序引起的。

另一个障碍是桌子的大小(729263行)。您不希望创建一个太宽的索引,因为它会占用更多空间并影响CUD操作的性能。我们想要做的是定位正在选择的列,但是,在这种情况下我们不能,因为它是一个计算列。您可以尝试创建VIEW或删除排序或在应用程序层执行此操作。