ran*_*rat 3 mysql mariadb index-tuning
我有 MySQL (MariaDB) 数据库。我有一个表“传感器”,它从物联网设备收集数据。
每个设备可以记录 4-6 个参数,如温度、湿度、空气质量等。每个设备每分钟发送一次测量值。
有 10-15 个这样的设备。每个设备都有它的deviceid。
六栏:
`autoid`(INT,AUTOICREMENT)
`deviceid`(varchar)
`pname`(varchar) /* name of parameter like temperature,humidty */
`pcode`(INT) /* code for each parameter like for temperature its 11,humidty its 12 etc */
`datavalue`(double) /* value of parameter */
`rectime`(INT) /* UNIX timestamp */
Run Code Online (Sandbox Code Playgroud)
以下是表数据示例:
自体 | 设备编号 | 名字 | 密码 | 数据值 | 重新计时 |
---|---|---|---|---|---|
1 | sdbjs4b | 温度 | 11 | 30.54 | 1621702300 |
2 | sdbjs4b | 哼 | 12 | 104 | 1621702300 |
3 | sdbjs4b | 气体 | 13 | 768 | 1621702300 |
4 | vsf5bjs | 温度 | 11 | 31.45 | 1621702300 |
5 | vsf5bjs | 伏特 | 15 | 5.10 | 1621702300 |
传感器表中几乎有4-5 百万行。
我的查询要求:我必须为每个设备和参数每天获取一些任意时间值的数据。
这是使用的查询:
SELECT * from sensors where deviceid =? AND pcode = ? AND rectime =?
Run Code Online (Sandbox Code Playgroud)
这保证只会给我一个结果。问题是我需要在嵌套循环中运行这个查询,最坏的情况是 500 次。为什么我需要循环?我需要为每个设备、参数以及两个日期之间的一组给定时间段创建两个日期之间的报告。我必须循环获取时隙的值。
我有一个综合指数上(deviceid,rectime,pcode)
。
如果我将此索引更改为 ,有什么区别(rectime,deviceid,pcode)
?
一般来说,如果我的查询使用 where 子句中的所有索引列,列顺序在复合索引中是否重要?
我认为您使用嵌套循环的方法是次优的。
为什么你不能做这样的事情:
select * from sensors where deviceid =? AND pcode = ? AND rectime between ? and ?
Run Code Online (Sandbox Code Playgroud)
这将返回整个数据集,您可以在本地处理它。在一个正确的选择中选择 500 或更多行比 500 个单行选择要好。
在这种情况下,我会将聚集索引更改为
(deviceid,pcode,rectime)
Run Code Online (Sandbox Code Playgroud)
您仍然可以保留 autoId 主键,只需将其设为非集群即可。
此外,根据您选择的工作方式,它必须在之后进行键查找才能获得一个额外的行。MySQL AFAIK 不支持包含索引,但即使如此,它也将是表的事实上重新排序的副本,因此聚集索引是有意义的。
至于顺序是否重要……嗯,是的,也不是。鉴于您的数据类型和表的大小,差异将是最小的。
归档时间: |
|
查看次数: |
94 次 |
最近记录: |