【发布时间】:2020-07-07 15:05:30
【问题描述】:
我使用的是 MySQL 5.7,下面的 sql 运行大约 10+ 秒,而总共只有 60K 数据,并且没有多少列,我不明白为什么它执行这么长时间。 为了优化 SQL,我添加了索引并更新了 SQL,但是没有用。
研究:当我删除 where 子句时,它运行 400ms,添加它并删除 count(*) 后,它也需要 400ms。
SELECT adt.data_source_id AS groupName, count(1) AS count
FROM assets_data_table adt
WHERE adt.is_deleted = 0
AND adt.tenant_id = 2
AND adt.sync_status = 1
GROUP BY adt.data_source_id;
如下所示显示我的表格 DDL:
create table assets_data_table
(
id bigint unsigned auto_increment comment 'pk'
primary key,
create_at datetime default CURRENT_TIMESTAMP not null comment 'create date',
update_at datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'update date',
create_by int default 0 not null ,
update_by int default 0 not null ,
is_deleted tinyint(1) default 0 not null comment '1 deleted,0 undeleted',
table_name varchar(100) not null ,
table_name_cn varchar(100) null ,
data_source_id bigint not null ,
sync_status tinyint(1) default 0 not null ,
db_id bigint not null ,
schema_name varchar(100) null ,
table_storage bigint default 0 not null ,
table_owner bigint default 0 not null ,
table_hot bigint default 0 not null ,
extra_attribute json null comment 'json string',
origin_table_id varchar(32) null ,
tenant_id bigint not null ,
sync_date datetime null ,
table_create_at datetime null
)
comment 'table';
# added to optimize sql
create index assets_data_table_ck
on assets_data_table (is_deleted, tenant_id, sync_status);
# added to optimize sql
create index assets_data_table_ck_1
on assets_data_table (is_deleted, tenant_id, sync_status, data_source_id);
create index idx_datasource_id
on assets_data_table (data_source_id);
create index idx_dbid
on assets_data_table (db_id);
解释:
| id | select\_type | table | partitions | type | possible\_keys | key | key\_len | ref | rows | filtered | Extra |
| 1 | SIMPLE | adt | NULL | ref | idx\_datasource\_id,assets\_data\_table\_ck,assets\_data\_table\_ck\_1 | assets\_data\_table\_ck\_1 | 10 | const,const,const | 28218 | 100 | Using where; Using index |
我的优化: 使用子查询,第一步:选择需要的列; 2.使用group by子句。它可以使用索引,只需要 400ms 执行。
SELECT adt.data_source_id AS groupName, count(*) AS count
FROM (select is_deleted, tenant_id, sync_status, data_source_id from assets_data_table
WHERE is_deleted = 0
AND tenant_id = 2
AND sync_status = 1) adt
GROUP BY adt.data_source_id;
| id | select\_type | table | partitions | type | possible\_keys | key | key\_len | ref | rows | filtered | Extra |
| 1 | SIMPLE | assets\_data\_table | NULL | ref | idx\_datasource\_id,assets\_data\_table\_ck,assets\_data\_table\_ck\_1 | assets\_data\_table\_ck\_1 | 10 | const,const,const | 28218 | 100 | Using where; Using index |
我的问题:
- 是否有其他方法可以优化此查询?
- group by 子句是如何工作的,为什么在我使用子查询之后它可以通过索引,它可以以其他方式使用索引吗?
谢谢!
【问题讨论】:
标签: mysql indexing group-by count