【问题描述】
同样的查询条件下,select *和count(1)查询速度差别很大。
SELECT * form t_meterorigvalue_std where F_CollectTime = '2018-04-09 01:20:30'; ---0.068s
SELECT count(1) form t_meterorigvalue_std where F_CollectTime = '2018-04-09 01:20:30'; ---7.844s
F_CollectTime是分区键
主键是('ID', 'F_CollectTime')
表结构:
CREATE TABLE `t_meterorigvalue_std` (
`ID` bigint(20) NOT NULL,
`F_OrigValueID` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
`F_BuildID` varchar(16) COLLATE utf8mb4_bin DEFAULT NULL,
`F_GateWayID` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`F_MeterParamID` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
`F_MeterID` smallint(6) DEFAULT NULL,
`F_Address` varchar(16) COLLATE utf8mb4_bin DEFAULT NULL,
`F_FunctionID` smallint(6) DEFAULT NULL,
`F_OrigValue` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
`F_CollectTime` datetime NOT NULL,
`F_ReceiveTime` datetime DEFAULT NULL,
`F_OrigStaCode` varchar(8) COLLATE utf8mb4_bin DEFAULT NULL,
`F_OrigErrCode` varchar(8) COLLATE utf8mb4_bin DEFAULT NULL,
`F_MeterType` smallint(6) DEFAULT NULL,
`F_PackType` smallint(6) DEFAULT NULL,
`F_ContinusHandle` smallint(8) DEFAULT NULL,
`F_CalcTime` datetime DEFAULT NULL,
`F_State` smallint(6) DEFAULT NULL,
`test_cl` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`ID`,`F_CollectTime`)
) ENGINE=SEQUOIADB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='sequoiadb:{"table_options":{"IsMainCL":true,"ShardingKey":{"F_CollectTime":1},\r\n"Compressed":true,"CompressionType":"lzw","ReplSize":1}}';
【解决办法】
1.检查执行语句的访问计划。
EXPLAN SELECT * form t_meterorigvalue_std where F_CollectTime = '2018-04-09 01:20:30'; 从访问计划可以看出该语句走的是表扫描。
EXPLAN SELECT count(1) form t_meterorigvalue_std where F_CollectTime = '2018-04-09 01:20:30'; 从访问计划可以看出该语句走的是索引扫描,用的索引是主键。
2.由于主键是 (`ID`,`F_CollectTime`) ,count(1)走索引扫描时会先根据ID进行索引排序后再查找F_CollectTime,所以花费的时间要比直接表扫描更多。
3.通过修改主键解决该问题,将F_CollectTime放在主键首位,如(‘F_CollectTime’, ‘ID’)。