我已经尝试了所有我能想到的方法来加速这个查询,但仍然需要大约 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/