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 

これにより、ユーザーが自分のアカウントに追加したサイトに基づいて記事のリストが出力されます。ランキングは、サブスコア列から構成されるスコアによって決定されます。

クエリは 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

このクエリを改善するための提案はありますか? ありがとうございました。

4

2 に答える 2

0

計算ロジックをクライアントに移動し、データベースからフィールドのみをロードします。これにより、クエリと計算自体が高速になります。SQLコードでそのようなことをするのは良いスタイルではありません。また、正規表現は非常に遅いので、「LIKE」のような別の検索モードの方が速いかもしれません。

于 2012-10-22T13:59:02.797 に答える
0

あなたの を見るとEXPLAIN、クエリがインデックスを利用しているようには見えません(したがって、ファイルソート)。これは、計算列 ( score) の並べ替えが原因です。

もう 1 つの障壁は、テーブルのサイズ (729263 行) です。幅が広すぎるインデックスは作成しないでください。より多くのスペースが必要になり、CUD 操作のパフォーマンスに影響を与えます。やりたいことは、選択されている列をターゲットにすることですが、この状況ではそれが計算列であるためできません。を作成するVIEWか、並べ替えを削除するか、アプリケーション層で実行できます。

于 2012-10-22T14:20:42.660 に答える