一次关于 Mysql 索引优化的思考
(给ImportNew加星标,提高Java技能)
www.jianshu.com/p/efb7881f18b2
查看系统性能监控,发现有十多条慢查询,决定将其优化。挑选其中一条典型Sql记录其优化历程。
1.概述
2.优化历程
2.1,定位问题
MySQL > show create table demo_table\G
*************************** 1\. row ***************************
Table: demo_table
Create Table: CREATE TABLE `demo_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` varchar(100) NOT NULL DEFAULT '' COMMENT '用户ID',
`source_channel` int(11) NOT NULL DEFAULT '0' COMMENT '来源',
`source_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '来源ID',
`category_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '分类ID',
`classify_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '归类时间',
`content_id` bigint(20) DEFAULT NULL COMMENT '语义模板ID',
PRIMARY KEY (`id`),
KEY `idx_category_id` (`category_id`),
KEY `idx_classify_time` (`classify_time`),
KEY `idx_channel_source_id` (`source_channel`,`source_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3081571 DEFAULT CHARSET=utf8mb4
select content_id, count(1) as c from demo_table where source_channel = 2
and classify_time between 1556019882000 and 1556624682000
and content_id is not null group by content_id;
id: 1
select_type: SIMPLE
table: demo_table
partitions: NULL
type: ref
possible_keys: idx_classify_time,idx_channel_source_id
key: idx_channel_source_id
key_len: 4
ref: const
rows: 1487434
filtered: 42.67
Extra: Using where; Using temporary; Using filesort
select content_id, count(1) as c from demo_table force index(idx_classify_time)
where source_channel = 2 and classify_time between 1556019882000
and 1556624682000 and content_id is not null group by content_id;
SQL-1
*************************** 1\. row ***************************
id: 1
select_type: SIMPLE
table: demo_table
partitions: NULL
type: ref
possible_keys: idx_classify_time,idx_channel_source_id
key: idx_channel_source_id
key_len: 4
ref: const
rows: 1487434
filtered: 42.67
Extra: Using where; Using temporary; Using filesort
SQL-2
*************************** 1\. row ***************************
id: 1
select_type: SIMPLE
table: demo_table
partitions: NULL
type: range
possible_keys: idx_classify_time
key: idx_classify_time
key_len: 8
ref: NULL
rows: 1410438
filtered: 45.00
Extra: Using where; Using temporary; Using filesort
2.2,解决方案
2.2.1 回表
2.2.2 覆盖索引
alter table `demo_table`add index
idx_content_id_calssify_time_source_channel(content_id,classify_time,source_channel);
再次执行SQL-1,显示耗时 0.02sec,性能成飞跃式提升。查看SQL-1执行计划:
id: 1
select_type: SIMPLE
table: demo_table
partitions: NULL
type: range
possible_keys:idx_classify_time,idx_channel_source_id,idx_channel_classify_time_content_id
key: idx_channel_classify_time_content_id
key_len: 21
ref: NULL
rows: 1788506
filtered: 50.00
Extra: Using where; Using index; Using temporary; Using filesort
从执行计划中,看Extra比之前多了个Using index,这就表示本次查询用到了覆盖索引,一般效率较高(基本达成三星索引的标准)。
至此,优化就结束了。
看完本文有收获?请转发分享给更多人
关注「ImportNew」,提升Java技能
好文章,我在看❤️