0

有人可以帮我解决这个问题吗?它工作正常,但需要太多时间。我确定问题出在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 .... 为什么?是答案。另一个有趣的读物是this。因此,您可能会考虑进一步重写查询。不幸的是,我现在没有更多的时间了。但是通过添加(复合)索引,您无论如何都会获得主要的性能提升。将索引放在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 回答