最初,数据库监控平台的SQL警报速度很慢。
SELECT * FROM t1 WHERE deduct_status = 1 AND bill_date = '2023-02-15' AND type IN (1, 2) AND gs_id IN (794872, 794873, 794874, 794875, 532720, 794868, 794869, 794870, 794871, 794864);
我首先查询了这个表的信息。表的结构如下。我省略了一些无关的敏感字段和注解。
CREATE TABLE `t1` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`gs_id` int(10) NOT NULL,
`bill_date` date NOT NULL ,
`account_user_id` bigint(20) NOT NULL DEFAULT '0',
`type` tinyint(2) NOT NULL DEFAULT '-1' ,
`bill_count` int(10) NOT NULL DEFAULT '0' ,
`deduct_status` tinyint(2) NOT NULL DEFAULT '0',
`deduct_amount` decimal(10, 2) NOT NULL DEFAULT '0.00',
`version` int(10) NOT NULL DEFAULT '0',
`gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`creator` varchar(50) NOT NULL DEFAULT '' ,
`gmt_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_gsid_billdate_type_accountid` (`gs_id`, `bill_date`, `type`, `account_user_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 377270771 DEFAULT CHARSET = utf8mb4
正常情况下,此SQL将通过唯一索引uk_gsid_billdate_type_accountid进行查询。
所以,我想可能是索引有问题,导致mysql的优化器选择不按索引查询。
然后我执行了下面的sql。
show INDEX from t1;
执行结果如下,我隐藏了表名:
以下是我认为有用的一些其他信息:
SELECT index_name, stat_name, stat_value, stat_description
FROM mysql.innodb_index_stats WHERE table_name like 't1';
show variables like 'innodb_stats%';
select version();
我想知道为什么基数是1,这是否是sql慢的原因。
过了一个晚上,我重新执行了这个sql,这个表恢复了正常,我什么都没做。
show INDEX from t1;
1条答案
按热度按时间soat7uwm1#
该索引可能以低基数
gs_id
开始。此外,该列未使用=
进行测试,因此优化程序将通过gs_id
。最佳索引类似于:
即便如此,前2列的基数可能不足以保证使用索引。
运行
ANALYZE TABLE t1;
;它 * 可以 * 更新基数。