为什么我类似的查询处理方式大不相同?

时间:2018-09-21 09:41:33

标签: mysql indexing query-performance

我们有一张桌子

  

mysql>显示创建表channeldata \ G
  *************************** 1.行******************** *******
         表格:channeldata
  创建表:CREATE TABLE channeldata
       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_idstation_idtime),
  使用BTREE的键composite3station_idchannel_idquality),
  键compositechannel_idstation_idtimequality)使用   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键,但是键区却大不相同。

1 个答案:

答案 0 :(得分:1)

您有一个错误。 MySQL无法识别时间常数中的T;将其更改为空格。

您应该切换到 InnoDB

在MyISAM中,将加快查询速度:

INDEX(channel_id, station_id,  -- in either order
      time,
      reading)   -- last

那将是“覆盖”的,因此比在索引和数据之间来回绑定要快。

返回为什么不同...我不知道。但是,以下任一 都可以帮助MyISAM表:ANALYZE TABLEOPTIMIZE TABLE