我们有一张桌子
mysql>显示创建表channeldata \ G
*************************** 1.行******************** *******
表格:channeldata
创建表:CREATE TABLEchanneldata
(
channel_id
smallint(3)unsigned NOT NULL,
station_id
smallint(5)unsigned NOT NULL,
time
日期时间NOT NULL,
reading
double NOT NULL缺省值'0',
average
双重NOT NULL 默认为'0',
location_lat
double NOT NULL缺省值'0',
location_lon
double NOT NULL缺省值'0',
location_alt
double(8,3)默认'0.000',
quality
smallint(3)未签名 默认为'0',
主键(channel_id
,station_id
,time
),
使用BTREE的键composite3
(station_id
,channel_id
,quality
),
键composite
(channel_id
,station_id
,time
,quality
)使用 BTREE)ENGINE = MyISAM DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci
设置1行(0.00秒)
最近,我注意到我们执行的某些选择查询需要花费很长时间才能完成。奇怪的是,根据where子句中列的值,select可能很快完成,或者需要很长时间才能阻止对该表的更新。我通过解释运行了这些查询:
mysql>解释SELECT读取来自channeldata的WHERE station_id = 6001
AND channel_id = 1 AND时间<'2018-09-20T14:58:00'\ G
*************************** 1.行******************** *******
id:1 select_type:SIMPLE
表格:channeldata
分区:NULL
类型:ref
可能的键:PRIMARY,composite3,composite
密码:PRIMARY
key_len:4
ref:const,const
行:176539
已过滤:33.33
附加:使用索引条件设置1行,1警告(0.00秒)mysql>解释SELECT read from channeldata WHERE station_id = 6001 AND channel_id = 4 AND时间<'2018-09-20T14:58:00'\ G
*************************** 1.行******************** *******
id:1 select_type:SIMPLE
表格:channeldata
分区:NULL
类型:范围
可能的键:PRIMARY,composite3,composite
密码:PRIMARY
key_len:9
参考:NULL
行:428073
已过滤:100.00
附加:使用索引条件设置1行,1警告(0.00秒)
为什么过滤其他值(channel_id为4而不是1)会有所不同?两个结果集大小相等。为什么在这两种情况下,MySQL都会选择使用PRIMARY键,但是键区却大不相同。
答案 0 :(得分:1)
您有一个错误。 MySQL无法识别时间常数中的T
;将其更改为空格。
您应该切换到 InnoDB 。
在MyISAM中,此将加快查询速度:
INDEX(channel_id, station_id, -- in either order
time,
reading) -- last
那将是“覆盖”的,因此比在索引和数据之间来回绑定要快。
返回为什么不同...我不知道。但是,以下任一 都可以帮助MyISAM表:ANALYZE TABLE
或OPTIMIZE TABLE
。