2012-10-22 113 views
2

我有,對於10+秒運行此查詢慢的問題:慢MySQL查詢與AS和子查詢

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上的索引。的 結果可以解釋:

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

我會將計算邏輯移動到客戶端,並只從數據庫加載字段。這使您的查詢和計算速度更快。在SQL代碼中做這樣的事情並不是一種好的風格。 也是正則表達式非常慢,也許像'LIKE'這樣的另一種搜索模式更快。

+0

謝謝。我比較了正則表達式和LIKE,但沒有顯着的收益。結果是成千上萬的故事,所以我不知道我應該加載這些所有的PHP,然後開始訂購。 – SvenV

0

看着你的EXPLAIN,它沒有出現你的查詢正在使用任何索引(因此filesort)。這是由計算列上的排序造成的(score)。

另一個障礙是表的大小(729263行)。您不希望創建太寬的索引,因爲它會佔用更多空間並影響CUD操作的性能。我們想要做的是定位正在選擇的列,但是,在這種情況下,我們不能,因爲它是一個計算列。您可以嘗試創建VIEW或者刪除排序或在應用程序層執行排序。