慢查询计数标签

时间:2015-12-23 20:24:55

标签: mysql

此查询统计与标签相关的视频(前50名)。它运行速度很慢(视频表大约有800k记录)。我已经设置了所有适当的索引/键。

SELECT `tags`.`id_tag`, `tags`.`tag_text`, COUNT(video_tags`.`id_video`) AS `total_video_count`
FROM `tags`
  INNER JOIN `video_tags` ON ( `tags`.`id_tag` = `video_tags`.`id_tag` )
  INNER JOIN `videos` ON ( `video_tags`.`id_video` = `videos`.`id_video` )
GROUP BY `tags`.`id_tag`
ORDER BY  `total_video_count` DESC
LIMIT 50;

有什么可能导致糟糕表现或任何其他方法来构建查询的想法?

----更新----

+--------+------------+------------------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name                                 | Seq_in_index | Column_name     | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+------------------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| videos |          0 | PRIMARY                                  |            1 | id_video        | A         |      812967 |     NULL | NULL   |      | BTREE      |         |               |
+--------+------------+------------------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

+------------+------------+---------------------------------------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table      | Non_unique | Key_name                                                | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+---------------------------------------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| video_tags |          0 | PRIMARY                                                 |            1 | id_video_tag | A         |     4113266 |     NULL | NULL   |      | BTREE      |         |               |
| video_tags |          1 | video_tags_id_tag_7e0eba6ebf2ab1be_fk_tags_id_tag       |            1 | id_tag       | A         |       10852 |     NULL | NULL   |      | BTREE      |         |               |
| video_tags |          1 | video_tags_id_video_6fa83a06b3a6ec45_fk_videos_id_video |            1 | id_video     | A         |     1371088 |     NULL | NULL   |      | BTREE      |         |               |
+------------+------------+---------------------------------------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tags  |          0 | PRIMARY  |            1 | id_tag      | A         |       35186 |     NULL | NULL   |      | BTREE      |         |               |
| tags  |          0 | tag_text |            1 | tag_text    | A         |       35186 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

2 个答案:

答案 0 :(得分:0)

SELECT
    `tags`.`id_tag`, 
    `tags`.`tag_text`,
    `ranking`.`total_video_count` as `total_video_count`
FROM tags
INNER JOIN (
    SELECT
        `video_tags`.`id_tag`,
        count(*) as total_video_count
    FROM `video_tags`
    GROUP BY `video_tags`.`id_tag`
    ORDER BY  `total_video_count` DESC
    LIMIT 50
) ranking ON ( `tags`.`id_tag` = `ranking`.`id_tag` )

可能存在一些错别字。无论如何,你得到了基本的想法。如果您加入两个大表,它应该会提高性能。

答案 1 :(得分:0)

以上最后评论是正确的..

在video_tags(id_tag,id_video)上添加索引。应该发生的是第一个左连接应该将新索引付诸行动。它会将id_video拉入内存并在内存中获得第二个左连接谓词..

我认为发生的事情是你正在对video_tags表进行另一次读取以拉入id_video列..这样就会对表中的非mem命中..然后如果video_tags中的行的物理布局不匹配PRIMARY KEY的序列(它可能使用的是什么)..你最终颠倒了IO

我会尝试在video_tags(id_tag,id_video)上添加复合键复合唯一键,然后再拍一次。