0

誰かがこのクエリを手伝ってくれますか? うまく機能していますが、時間がかかりすぎます。の OR ステートメントが多すぎることが問題であると判断しましたtb_activities。このクエリを高速化するアイデアはありますか?

SELECT tb_posts.*
FROM   tb_posts
WHERE  EXISTS (SELECT c_id
               FROM   tb_users
               WHERE  tb_posts.c_uid = tb_users.c_id
                      AND tb_users.c_tokens > 0)
       AND NOT EXISTS (SELECT c_id
                       FROM   tb_activities
                       WHERE  tb_posts.c_url = tb_activities.c_url
                              AND tb_activities.c_category = 'gplus'
                              AND ( tb_activities.c_uid LIKE '%,6x1,%'
                                     OR tb_activities.c_uid LIKE '%,6x1'
                                     OR tb_activities.c_uid LIKE '6x1,%'
                                     OR tb_activities.c_uid = '6x1' ))
       AND NOT EXISTS (SELECT c_id
                       FROM   tb_blacklist
                       WHERE  tb_posts.c_url LIKE Concat('%', tb_blacklist.c_url
                                                  , '%')
                              AND tb_blacklist.c_times > 2
                              AND tb_blacklist.c_category = 'gplus')
       AND tb_posts.c_category = 'classic'
       AND tb_posts.c_status = 'run'
       AND tb_posts.c_nogplus = 0
GROUP  BY tb_posts.c_url
ORDER  BY tb_posts.c_cost DESC,
          tb_posts.c_date DESC
LIMIT  30  
4

1 に答える 1

1

ここで行ったことは、最初のWHERE EXISTS .... なんで?これが答えです。別の興味深い読み物はこれです。そのため、クエリをさらに書き直すことを検討してください。残念ながら、今はもう時間がありません。ただし、(複合)インデックスを追加することで、主なパフォーマンスが向上します。s の基になる列、または句で頻繁に使用される列に索引を付けます。JOINWHERE

SELECT tb_posts.*
FROM   tb_posts
INNER JOIN tb_users ON tb_posts.c_uid = tb_users.c_id
WHERE  tb_users.c_tokens > 0
       AND NOT EXISTS (SELECT c_id
                       FROM   tb_activities
                       WHERE  tb_posts.c_url = tb_activities.c_url
                              AND tb_activities.c_category = 'gplus'
                              AND ( tb_activities.c_uid LIKE '%,6x1,%'
                                     OR tb_activities.c_uid LIKE '%,6x1'
                                     OR tb_activities.c_uid LIKE '6x1,%'
                                     OR tb_activities.c_uid = '6x1' ))
       AND NOT EXISTS (SELECT c_id
                       FROM   tb_blacklist
                       WHERE  tb_posts.c_url LIKE Concat('%', tb_blacklist.c_url, '%')
                              AND tb_blacklist.c_times > 2
                              AND tb_blacklist.c_category = 'gplus')
       AND tb_posts.c_category = 'classic'
       AND tb_posts.c_status = 'run'
       AND tb_posts.c_nogplus = 0
GROUP  BY tb_posts.c_url
ORDER  BY tb_posts.c_cost DESC,
          tb_posts.c_date DESC
LIMIT  30

EXPLAINまた、どのインデックスが使用されているか (または使用されていないか) がわかるように、について読みたいと思うかもしれません。

余談ですが、句の順序を変更することに関する Peter Kiss のヒントWHEREはナンセンスです。とにかく、クエリ オプティマイザはこれを処理します。

于 2012-08-10T16:35:53.553 に答える