我在 MySQL 上遇到性能问题,并且我无法理解我错在哪里。该计算机运行 MySQLServer 5.7.15,具有两个 Xeon 64 位处理器 和 8GBytes RAM。 我有两个表:
表data_raw包含多个字段(参见VRMS0、VRMS1、VRMS2、PWRA0 em>,PWRA1,PWRA2)
描述从现场多个探头的复杂仪器每 30 秒获取的电压和有功功率,每个探头均由其DEVICE_ID唯一标识。
表data_timeslot包含几个字段,用于跟踪单个data_raw记录的发送时间(参见SRV_TIMESTAMP字段)
以及来自哪个设备(请参阅DEVICE_ID字段)。
每个表包含大约7.800.000 条记录。 这两个表使用data_timeslot上的ID(自动增量)上的PK和data_timeslot上的PK进行连接。 em>TIMESLOT_ID(自动递增)在 data_timeslot 上。 这是查询:
SELECT D.VRMS0,D.VRMS1,D.VRMS2,D.PWRA0,D.PWRA1,D.PWRA2,T.DEVICE_ID, T.SRV_TIMESTAMP
FROM data_raw AS D FORCE INDEX(PRIMARY)
INNER JOIN data_timeslots AS T ON T.ID=D.TIMESLOT_ID
WHERE T.DEVICE_ID='CEC02'
ORDER BY T.ID DESC LIMIT 1
查询总是需要 10 秒,而对单个表的相同查询需要几毫秒。 换句话说,查询
SELECT * FROM 'data_raw' order by TIMESLOT_ID desc limit 1
只需 0.0071 秒,查询即可
SELECT * FROM 'data_timeslots' order by ID desc limit 1
只需要 0.0042 秒,所以我想知道为什么连接需要这么长时间。
瓶颈在哪里?
附言“扩展”表明数据库正在正确使用 PK 进行操作。 扩展打印输出下方:
`解释 SELECT D.VRMS0、D.VRMS1、D.VRMS2、D.PWRA0、D.PWRA1、D.PWRA2、T.DEVICE_ID、T.SRV_TIMESTAMP FROM data_raw AS D INNER JOIN data_timeslots A T ON T.ID =D.TIMESLOT_ID WHERE T.DEVICE_ID='XXXXX' 按 T.ID ASC 限制 1 排序
<小时/>1 SIMPLE T 索引 PRIMARY,PK_CLUSTER_T,DEVICE_ID PRIMARY 8 30 3.23 使用位置
<小时/>1 SIMPLE D eq_ref PRIMARY PRIMARY 8 splc_smartpwr.T.ID 1 100.00 NULL`
更新(由@Alberto_Delgado_Roda建议):如果我使用ASC LIMIT 1,查询只需 0,0261 秒
最佳答案
回复“为什么”
Data_timeslots 有一个适合升序的聚集索引
聚集索引如何加速查询
通过聚集索引访问行速度很快,因为索引搜索直接指向包含所有行数据的页面。如果表很大,则与使用与索引记录不同的页存储行数据的存储组织相比,聚集索引架构通常可以节省磁盘 I/O 操作。 (例如,MyISAM 使用一个文件存储数据行,使用另一个文件存储索引记录。)
参见https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html
关于简单的两个表连接查询的 MySQL 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39821669/