Mysql 提高此SQL的查询性能
我想提高这个查询的性能,现在返回结果需要13秒 主表有200多万条记录。结果仅包含34条记录。表中有r.date\u gps的索引 不幸的是,Mysql不支持行数窗口函数 尝试将子查询重新写入内部联接Mysql 提高此SQL的查询性能,mysql,sql,mariadb,Mysql,Sql,Mariadb,我想提高这个查询的性能,现在返回结果需要13秒 主表有200多万条记录。结果仅包含34条记录。表中有r.date\u gps的索引 不幸的是,Mysql不支持行数窗口函数 尝试将子查询重新写入内部联接 在考虑提高查询性能时,首先要考虑FROM和WHERE子句: 这些建议索引包括客户管理id、id、车辆客户id、id、安装车辆id、跟踪器id、跟踪器跟踪器id、cod和注册表SN、日期gps 这将从本质上鼓励优化器从clients表开始实现连接,根据management_id进行过滤。然后连接将只
在考虑提高查询性能时,首先要考虑FROM和WHERE子句: 这些建议索引包括客户管理id、id、车辆客户id、id、安装车辆id、跟踪器id、跟踪器跟踪器id、cod和注册表SN、日期gps
这将从本质上鼓励优化器从clients表开始实现连接,根据management_id进行过滤。然后连接将只使用索引,查询的这一部分应该非常快。当然,如果您有数千或数百万个匹配项,那么GROUP BY仍然会降低查询速度,MySQL也没有多少选项可以提高GROUP BY的性能。要使用这些数据加快查询速度,首先必须收缩maintable。有时两个查询比一个好 首先尝试获取您的WHERE数据
SELECT MAX(rr.date_gps) FROM registers rr WHERE r.sn = rr.sn
然后使用结果将其添加到主查询中
在这里,也可以先使用子查询,然后再连接到其他表
比如说
SELECT registers.*
FROM (
SELECT registers.id
FROM registers
WHERE <My WHERE Conditions>
) AS registers_sub
INNER JOIN registers
ON registers_sub.id = registers.id
然后执行其余的查询。所以当你进行大量的连接和分组时,你会得到一小部分数据
最后一个提示是,如果你不需要所有东西,就不要在SELECT段中使用*;D
您好感谢大家为提高查询性能所提供的帮助 VR46已将查询改写为这种格式,但主银行的速度仍然很慢 ZFNerd也分为两个查询,出现同样的慢度。 Gordon Linoff,这些字段已经被索引了 我有一个查询,使用另一个字段来获取最新的数据,但这不是我想要的,因为一些设备在最旧的数据之后首先发送当前数据,因此最终很难找到最新的记录。 但有些可以配置为最早先发送。 我想现在我会使用这种格式,因为更新速度很快,问题也会很小
SELECT c.name,CONCAT(v.title,' ',v.plaque) AS title,v.type_vehicle,r.id,
r.sn,r.lat,r.lng, r.direction,r.date_db,r.date_gps,r.volt_main,r.speed,
r.ign,r.sat_fix,r.sat
FROM registers r
JOIN trackers t ON t.cod = r.sn
JOIN installations i ON t.id = i.trackers_id
JOIN vehicles v ON v.id = i.vehicles_id
JOIN clients c ON c.id = v.clients_id
JOIN (
SELECT rr.sn, MAX(rr.id) AS id FROM registers rr GROUP BY sn
) AS L2 ON r.sn = L2.sn AND r.id = L2.id
AND c.management_id = p_management
GROUP BY r.sn;
尽管其他查询可能通过select max group by有所帮助,但您最好选择另一条路线。您似乎正在跟踪运输某种类型货物的车辆,并希望在任何给定点获得最新位置 更新Trackers表并为LastGPSDate添加一列可能会更好。然后,在插入到Date_GPS表时,通过触发器向相应的Trackers.LastGPSDate发出更新,其中COD=根据join子句插入的GPS.sn。然后您的查询将简化为
SELECT
r.id,
c.name,
CONCAT(v.title, '', v.plaque) AS title,v.type_vehicle,
r.sn,
r.lat,
r.lng,
r.direction,
r.date_db,
r.date_gps,
r.volt_main,
r.speed,
r.ing,
t.sat_fix,
r.sat
FROM
clients c
JOIN vehicles v
ON c.id = v.clients_id
JOIN installations i
ON v.id = i.vehicles_id
join trackers t
ON i.trackers_id = t.id
JOIN registers r
ON t.cod = r.sn
AND t.LastGPSDate = r.date_gps
WHERE
c.management_id = p_management
ORDER BY
t.LastGPSDate DESC;
我颠倒了桌子的顺序,以便更好地匹配您要找的东西。通过管理ID从一个具有特定位置的客户端开始。然后,只有他们的车辆才能安装、跟踪并最终注册
然后,我建议使用以下索引
表索引
客户管理_id,id
车辆识别码,客户识别码
安装跟踪器\u id,车辆\u id
追踪器最新GPSDate、cod、id、卫星定位
注册序列号、日期和gps
由于join子句专门限制一个管理ID,因此我将其放在索引的第一个位置
因此,在200多万条记录中,您的大部分数据可能有20、30、100个不同的管理ID,为什么每次运行时都会生成一个应用于所有寄存器的最大值。通过触发器每次标记一次日期/时间,您可以更快地获得数据,并且只针对您当时需要的客户机。您是否检查了解释计划?请将查询执行计划添加到问题中。我不清楚如何聚合整个registers表而不是只查找匹配的行来提高性能。听到OP的回音会很有趣。
SELECT registers.*
FROM (
SELECT registers.id
FROM registers
WHERE <My WHERE Conditions>
) AS registers_sub
INNER JOIN registers
ON registers_sub.id = registers.id
SELECT c.name,CONCAT(v.title,' ',v.plaque) AS title,v.type_vehicle,r.id,
r.sn,r.lat,r.lng, r.direction,r.date_db,r.date_gps,r.volt_main,r.speed,
r.ign,r.sat_fix,r.sat
FROM registers r
JOIN trackers t ON t.cod = r.sn
JOIN installations i ON t.id = i.trackers_id
JOIN vehicles v ON v.id = i.vehicles_id
JOIN clients c ON c.id = v.clients_id
JOIN (
SELECT rr.sn, MAX(rr.id) AS id FROM registers rr GROUP BY sn
) AS L2 ON r.sn = L2.sn AND r.id = L2.id
AND c.management_id = p_management
GROUP BY r.sn;
SELECT
r.id,
c.name,
CONCAT(v.title, '', v.plaque) AS title,v.type_vehicle,
r.sn,
r.lat,
r.lng,
r.direction,
r.date_db,
r.date_gps,
r.volt_main,
r.speed,
r.ing,
t.sat_fix,
r.sat
FROM
clients c
JOIN vehicles v
ON c.id = v.clients_id
JOIN installations i
ON v.id = i.vehicles_id
join trackers t
ON i.trackers_id = t.id
JOIN registers r
ON t.cod = r.sn
AND t.LastGPSDate = r.date_gps
WHERE
c.management_id = p_management
ORDER BY
t.LastGPSDate DESC;