可以使这个SQL查询更快?

时间:2012-04-16 05:30:58

标签: mysql

只是好奇是否可以更快地进行此查询?或者是否有其他类似的查询可以更好地运作?

SELECT id,source FROM posts
WHERE id = ANY(SELECT image_id FROM `post_tags` WHERE tag_id = (SELECT id FROM `tags` WHERE tag = _utf8 '$TAG' collate utf8_bin))
  AND posts.exists = 'n'
ORDER BY posts.ratecount DESC
LIMIT 0,100

不使用:

  AND posts.exists = 'n'
ORDER BY posts.ratecount
DESC LIMIT 0,100

它加速查询到可用的级别,但有些需要我正在做的事情。

  • 标签表包含'tag'和'id'的唯一索引。
  • 标签有83K行。
  • Post_tags具有'image_id','tag_id'的唯一索引。也是每个人的正常指数。
  • Post_tags有471K行。
  • 帖子有'id'的唯一索引。也是'exists'和'ratecount'的正常索引。
  • 帖子表大约有1.1M行。

2 个答案:

答案 0 :(得分:0)

你的TAG表是什么样的?它只包含ID和TAG字段吗?我会在TAG(TAG, ID)上创建一个唯一索引,因此最内层的查询只搜索索引。

POST_TAGS表怎么样?它只是TAG_ID和IMAGE_ID的组合吗?我再次在POST_TAGS(IMAGE_ID, TAG_ID)上创建一个唯一索引。

请注意索引中字段的顺序很重要,POST_TAGS(TAG_ID, IMAGE_ID)上的索引与解析计划中POST_TAGS(IMAGE_ID, TAG_ID)上的索引差别很大。

POSTS(ID, POSTS, RATEACCOUNT)上具有唯一索引的POSTS表中可以提供帮助,(我知道它是一个冗余索引,并且在INSERT,UPDATE和DELETE上会产生额外的成本,但它会帮助您进行此查询)

顺便说一下,在内部查询中使用JOIN可能会提高性能,只需检查它。

答案 1 :(得分:0)

根据有人建议,使用JOIN管理它。

SELECT * FROM posts
LEFT JOIN post_tags ON post_tags.image_id = posts.id
JOIN tags ON post_tags.tag_id = tags.id
WHERE tags.tag = _utf8 '$tag' collate utf8_bin
  AND posts.exists = 'n'
ORDER BY posts.ratecount DESC
LIMIT 0,100

减少从22秒开始的时间> 0.26s。