【发布时间】:2016-10-02 21:01:54
【问题描述】:
我在 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(自动增量)和 PK 上的 data_timeslot 上的 em>TIMESLOT_ID(自动递增)。 这是查询:
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 进行操作。 在扩展打印输出下方:
`EXPLAIN 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 AS T ON T.ID =D.TIMESLOT_ID WHERE T.DEVICE_ID='XXXXX' ORDER BY T.ID ASC LIMIT 1
1 SIMPLE T index PRIMARY,PK_CLUSTER_T,DEVICE_ID PRIMARY 8 30 3.23 使用where
1 SIMPLE D eq_ref PRIMARY PRIMARY 8 splc_smartpwr.T.ID 1 100.00 NULL`
更新(@Alberto_Delgado_Roda 建议):如果我使用 ASC LIMIT 1,查询只需 0,0261 秒
【问题讨论】:
-
您需要在
DEVICE_ID(和timeslot_id,但您已经在使用)的索引。 -
请附上 2 表查询的解释计划。每个表中索引了哪些列?为什么要强制索引主要?如果你不这样做会怎样?
-
@Used_By_Already : FORCE INDEX 只是为了解决这个问题。如果我不使用它,结果是相同的(因为已经使用了主键)。在解释文本结果上方
-
@Solarflare:在 data_timestamps 上已经有 ID (PKey)、DEVICE_ID、SRV_TIMESTAMP 和 DEVICE_ID+SRV_TIMESTAMP(集群索引)上的覆盖索引。在 data_raw 上,唯一可能的索引位于 TIMESLOT_ID
-
尝试在
DEVICE_ID上强制索引。