2

我对这个运行 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 

这会根据用户添加到其帐户的站点输出故事列表。排名由分数决定,分数由子分数列组成。

该查询使用文件排序并使用 PRIMARY 和 feedid 上的索引。解释的结果:

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

有什么改进这个查询的建议吗?谢谢你。

4

2 回答 2

0

我会将计算逻辑移动到客户端,并且只从数据库中加载字段。这使您的查询和计算本身更快。在 SQL 代码中做这样的事情不是一种好的风格。而且正则表达式也很慢,也许像“LIKE”这样的另一种搜索模式更快。

于 2012-10-22T13:59:02.797 回答
0

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

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

于 2012-10-22T14:20:42.660 回答