Mysql-加快200万行的select查询

Mysql-加快200万行的select查询,mysql,query-optimization,Mysql,Query Optimization,我有一张像下面这样的桌子 Field Type Null Key Default Extra id bigint(11) NO PRI NULL auto_increment deviceId bigint(11) NO MUL NULL value double NO NULL time timestamp YES MUL 0000-

我有一张像下面这样的桌子

Field    Type      Null Key Default               Extra

id       bigint(11) NO  PRI NULL                  auto_increment
deviceId bigint(11) NO  MUL NULL        
value    double     NO      NULL        
time    timestamp   YES MUL 0000-00-00 00:00:00 
ALTER TABLE `sensor_value` 
 ADD INDEX `IDX_FIELDS1_2` (`time`, `deviceId`) ;
它有200多万行。当我运行select*from tableName时;这需要超过15分钟

当我运行select value(选择值)时,来自传感器的时间值,其中时间>'2017-05-21 04:47:48',设备ID>=812;加载时间超过45秒

注意:512有超过92514行。 即使我为下面这样的列添加了索引

Field    Type      Null Key Default               Extra

id       bigint(11) NO  PRI NULL                  auto_increment
deviceId bigint(11) NO  MUL NULL        
value    double     NO      NULL        
time    timestamp   YES MUL 0000-00-00 00:00:00 
ALTER TABLE `sensor_value` 
 ADD INDEX `IDX_FIELDS1_2` (`time`, `deviceId`) ;

如何使选择查询快速?在1秒内加载我是否索引错误?

使用组合索引时,通常必须在第一列上使用相等运算符,然后才能在第二列上使用范围条件。因此,我建议您更改索引中列的顺序,如下所示:

ALTER TABLE `sensor_value` 
 ADD INDEX `IDX_FIELDS1_2` (`deviceId`, `time`) ;
然后更改为对deviceId使用等号deviceId=812而不是deviceId>=812:

我希望这能有所帮助


200万条记录对Mysql来说不算多,如果你做对了,10亿条记录在不到1秒的时间内得到结果是正常的。

只有4列?听起来您的RAM很小,或者innodb_buffer_pool_size设置得太低。因此,您严重受到I/O绑定和/或交换的影响

WHERE time > '2017-05-21 04:47:48'
  AND deviceId >= 812
是两个范围。没有彻底的方法来优化它。这两个都会有帮助。如果两者都有,优化器可能会选择更好的:

INDEX(time)
INDEX(deviceId)
在InnoDB中使用“二级”索引时,查询首先在索引BTree中查找;当存在匹配项时,它必须使用主键在“数据”B树中进行查找

在尝试INDEXtime、deviceId时,您会看到一些异常情况,这是因为过滤不必像以前那样频繁地访问数据

除了唯一性之外,您是否使用id?deviceId和time对是否唯一?如果答案是“否”和“是”,则去掉id并改为主键设备id,time。或者你可以交换这两列。你还有什么其他疑问


去掉id会使表格缩小一些,从而减少I/O。

请包含您选择的解释结果。您的覆盖索引可能应该是deviceId然后是time。因为这可能会在使用时间范围之前有效地减少记录。请提供更多信息,如您创建的索引的基数,并解释该语句。但是,如果OP确实需要>=812,则与此无关。正确缩小记录范围很重要。如果>=812中的行数很少,那么索引就很有用。但通常情况下,我们不能对索引的两列都使用范围,而期望有良好的性能。在这种情况下,使用单独的索引会更好。MySQL几乎从不在一个SELECT索引合并中使用两个索引。当它这样做时,成本相当高-创建两个临时表,“交叉”它们,然后最终查找行。@RickJames您是对的,但正如您在回答中提到的,它可以帮助Mysql根据查询条件选择更好的索引。在我在my.cnf文件中设置innodb_buffer_pool_size=1073741824之后,它可以在5秒内加载。你有多少内存?我总共有8GB的内存,但有2GB的可用空间,但在我将buffe_大小设置为1GB后,需要84%的内存空间。我认为这仍然不是一个很好的解决方案,以增加到1GP。