mysql - 如何加速MySQL查询: order by count

标签 mysql performance tags aggregate

我已经尝试了所有我能想到的方法来加速这个查询,但仍然需要大约 2.5 秒。

该表是 images_tags(约 400 万行): 这是表格说明:

Field       Type               Null     Key     Default
image_ids   int(7) unsigned    NO       PRI     NULL
tags_id     int(7) unsigned    NO       PRI     NULL

以下是索引:

Table         Non_unique  Key_name      Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null  Index_type
images_tags   0           PRIMARY       1             image_ids    A          NULL         NULL      NULL          BTREE
images_tags   0           PRIMARY       2             tags_id      A          4408605      NULL      NULL          BTREE
images_tags   1           image_ids     1             image_ids    A          734767       NULL      NULL          BTREE

这是查询:

select image_ids
from images_tags
where tags_id in (1, 2, 21, 846, 3175, 4290, 6591, 9357, 9594, 14289, 43364, 135019, 151295, 208803, 704452)
group by image_ids
order by count(*) desc
limit 10

这是查询解释:

select_type  table        type   possible_keys  key                 key_len  ref   rows     Extra
SIMPLE       vids_x_tags  index  join_tags_id   join_vids_id_unique  8       NULL  4408605  Using where; Using index; Using temporary; Using filesort

目标是获取与这些标签最匹配的 10 张图像。 我尝试过修改这些变量,但几乎没有任何改进:

  • 最大堆表大小
  • tmp_table_size
  • myisam_sort_buffer_size
  • 读取缓冲区大小
  • 排序缓冲区大小
  • read_rnd_buffer_size
  • net_buffer_length
  • 预加载缓冲区大小
  • key_buffer_size

有什么方法可以大大加快这个查询的速度吗?大约有 700K 个图像,而且它总是在增长,所以我不想将结果缓存超过一两天,并且必须对每个图像执行此操作,因此重新缓存如此多的查询是不可能的。

最佳答案

在这种链接(联结、多对多)表中,在 (a, b)(b, a)。您只有其中一个(主索引),而没有另一个。

如果表中没有其他列,则根本不需要任何其他索引。

因此,您应该添加 (tags_id, image_ids) 索引并删除多余的 (image_ids) 索引:

ALTER TABLE images_tags
  DROP INDEX image_ids,
  ADD INDEX tag_image_IDX           -- choose a name for the index
    (tags_id, image_ids) ;

针对特定查询的索引效率取决于很多因素,主要取决于图像和标签的分布(IN 列表中的 15 个标签有多受欢迎?)

关于mysql - 如何加速MySQL查询: order by count,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12595964/

相关文章:

attributes - <script> 嵌入被 HTML Purifier(最新的 4.8.0)移除

user-interface - 为什么标签应该用空格分隔?

mysql - 将数据从一个不断附加的文件中分离到一个新文件中

php - 为什么即使我传递了错误的用户名,mysqli_connect() 也返回 true?

c++ - 试除法代码在 Windows 上运行 32 位比在 Linux 上运行 64 位快 2 倍

performance - 大量的调试日志会减慢我的 (grails) web 应用程序的速度吗?

Android NFC 扫描时间

mysql - Bash - 在输出中获取循环的反向计数

html - 使用 MySQL 生成自定义报告

c++ - if 中的多个语句是否与多个 if 相同?