同一数据库上的 2 个几乎相同的选择 table 执行时间大不相同
2 almost Identical selects on same DB table takes vastly different time to execute
圣诞节,我有一个问题,我真的很难找到关于如何处理的线索..
我有一个报告数据库,它由许多小型机器上的卫星数据库中的数据填充。每个卫星数据库每 20 分钟平均执行一次数据提取。他们使用所有相同的脚本。然而,它们在不同的装置上,分布在全国各地。
现在我有一个 SELECT,供 pentaho 报告在该报告数据库中的同一数据库 table 上执行。一个 SELECT 需要几毫秒才能执行,而另一个需要几个小时。它们都在相同的table、相同的数据库运行、相同的硬件上执行。
快一个:
SELECT
res.ticket_id,
res.entry_zone,
res.entry_time,
res.exit_time,
res.parking_time,
res.cost,
co.org_name,
cu.firstname,
cu.surname,
a.name AS article_name,
res.car_id
FROM (SELECT
lh.ticket_id,
z.name AS entry_zone,
lh.park_entered AS entry_time,
lh.park_leaved AS exit_time,
interval_to_hourminsec(lh.park_leaved - lh.park_entered) AS parking_time,
lh.cost,
lh.article_id,
sa.contrib_user_id,
fpl.car_id
FROM longterm_history lh, zones z, sold_articles sa, flexcore_passing_log fpl
WHERE lh.park_leaved BETWEEN '2017-12-18 00:00' AND '2017-12-19 23:59'
AND sa.ticket_id = lh.ticket_id
AND lh.entry_zone = z.zone_number
AND lh.passlog_id = fpl.id
AND lh.park_uuid = 100068
AND z.park_uuid = 100068
AND sa.park_uuid = 100068
AND fpl.park_uuid = 100068
AND lh.entry_zone = 1
) AS res
LEFT OUTER JOIN articles a ON res.article_id = a.article_id AND a.park_uuid = 100068
LEFT OUTER JOIN cont_users cu ON res.contrib_user_id = cu.id AND cu.park_uuid = 100068
LEFT OUTER JOIN cont_orgs co ON cu.org_id = co.id AND co.park_uuid = 100068
ORDER BY res.exit_time ASC
慢:
SELECT
res.ticket_id,
res.entry_zone,
res.entry_time,
res.exit_time,
res.parking_time,
res.cost,
co.org_name,
cu.firstname,
cu.surname,
a.name AS article_name,
res.car_id
FROM (SELECT
lh.ticket_id,
z.name AS entry_zone,
lh.park_entered AS entry_time,
lh.park_leaved AS exit_time,
interval_to_hourminsec(lh.park_leaved - lh.park_entered) AS parking_time,
lh.cost,
lh.article_id,
sa.contrib_user_id,
fpl.car_id
FROM longterm_history lh, zones z, sold_articles sa, flexcore_passing_log fpl
WHERE lh.park_leaved BETWEEN '2017-12-18 00:00' AND '2017-12-19 23:59'
AND sa.ticket_id = lh.ticket_id
AND lh.entry_zone = z.zone_number
AND lh.passlog_id = fpl.id
AND lh.park_uuid = 100146
AND z.park_uuid = 100146
AND sa.park_uuid = 100146
AND fpl.park_uuid = 100146
AND lh.entry_zone = 1
) AS res
LEFT OUTER JOIN articles a ON res.article_id = a.article_id AND a.park_uuid = 100146
LEFT OUTER JOIN cont_users cu ON res.contrib_user_id = cu.id AND cu.park_uuid = 100146
LEFT OUTER JOIN cont_orgs co ON cu.org_id = co.id AND co.park_uuid = 100146
ORDER BY res.exit_time ASC
如何找出问题出在哪里,是什么导致第二个SELECT执行小时?
我正在使用 postgres SQL,服务器版本是 9.6.3
pentaho data-integration
将数据提取到数据库中
编辑:
在 运行 两个查询之后 EXPLAIN (ANALYZE, BUFFERS)
最大的显着差异是在这部分:
-> Bitmap Index Scan on longterm_history_park_uuid_idx (cost=0.00..7609.82 rows=352718 width=0) (actual time=492.753..492.753 rows=354537 loops=1)
Index Cond: (park_uuid = 100068)
Buffers: shared read=1238
-> Bitmap Index Scan on longterm_history_park_uuid_idx (cost=0.00..453.11 rows=20890 width=0) (actual time=4.680..4.680 rows=40021 loops=466475)
Index Cond: (park_uuid = 100146)
Buffers: shared hit=65306361 read=139
似乎让第二个 SELECT 变慢的是 loops=466475
而不是第一个 SELECT 造成的 loops=1
。但我不知道这意味着什么或如何解决它..
编辑2:
我找到了可以在线分享计划的工具,这里是链接:
快速查询:https://explain.depesz.com/s/oYQLB
慢查询:https://explain.depesz.com/s/uOtf
慢速查询执行得很快,而提取已关闭:https://explain.depesz.com/s/4h4F
问题已解决。
在许多基于网络的工具的帮助下学习如何阅读 EXPLAIN ANALYZE
以图形化显示它之后,我注意到第二个(较慢)select 正在执行大量循环并且优化器期望更少实际要返回的行数 returns.
这是优化器计算所基于的错误数据的迹象。为了解决它,我在整个数据库上有 运行 VACUUM ANALYZE
。
结果是性能显着提高,查询执行时间缩短了从 4265437.080 毫秒 到 547.202 毫秒
圣诞节,我有一个问题,我真的很难找到关于如何处理的线索..
我有一个报告数据库,它由许多小型机器上的卫星数据库中的数据填充。每个卫星数据库每 20 分钟平均执行一次数据提取。他们使用所有相同的脚本。然而,它们在不同的装置上,分布在全国各地。
现在我有一个 SELECT,供 pentaho 报告在该报告数据库中的同一数据库 table 上执行。一个 SELECT 需要几毫秒才能执行,而另一个需要几个小时。它们都在相同的table、相同的数据库运行、相同的硬件上执行。
快一个:
SELECT
res.ticket_id,
res.entry_zone,
res.entry_time,
res.exit_time,
res.parking_time,
res.cost,
co.org_name,
cu.firstname,
cu.surname,
a.name AS article_name,
res.car_id
FROM (SELECT
lh.ticket_id,
z.name AS entry_zone,
lh.park_entered AS entry_time,
lh.park_leaved AS exit_time,
interval_to_hourminsec(lh.park_leaved - lh.park_entered) AS parking_time,
lh.cost,
lh.article_id,
sa.contrib_user_id,
fpl.car_id
FROM longterm_history lh, zones z, sold_articles sa, flexcore_passing_log fpl
WHERE lh.park_leaved BETWEEN '2017-12-18 00:00' AND '2017-12-19 23:59'
AND sa.ticket_id = lh.ticket_id
AND lh.entry_zone = z.zone_number
AND lh.passlog_id = fpl.id
AND lh.park_uuid = 100068
AND z.park_uuid = 100068
AND sa.park_uuid = 100068
AND fpl.park_uuid = 100068
AND lh.entry_zone = 1
) AS res
LEFT OUTER JOIN articles a ON res.article_id = a.article_id AND a.park_uuid = 100068
LEFT OUTER JOIN cont_users cu ON res.contrib_user_id = cu.id AND cu.park_uuid = 100068
LEFT OUTER JOIN cont_orgs co ON cu.org_id = co.id AND co.park_uuid = 100068
ORDER BY res.exit_time ASC
慢:
SELECT
res.ticket_id,
res.entry_zone,
res.entry_time,
res.exit_time,
res.parking_time,
res.cost,
co.org_name,
cu.firstname,
cu.surname,
a.name AS article_name,
res.car_id
FROM (SELECT
lh.ticket_id,
z.name AS entry_zone,
lh.park_entered AS entry_time,
lh.park_leaved AS exit_time,
interval_to_hourminsec(lh.park_leaved - lh.park_entered) AS parking_time,
lh.cost,
lh.article_id,
sa.contrib_user_id,
fpl.car_id
FROM longterm_history lh, zones z, sold_articles sa, flexcore_passing_log fpl
WHERE lh.park_leaved BETWEEN '2017-12-18 00:00' AND '2017-12-19 23:59'
AND sa.ticket_id = lh.ticket_id
AND lh.entry_zone = z.zone_number
AND lh.passlog_id = fpl.id
AND lh.park_uuid = 100146
AND z.park_uuid = 100146
AND sa.park_uuid = 100146
AND fpl.park_uuid = 100146
AND lh.entry_zone = 1
) AS res
LEFT OUTER JOIN articles a ON res.article_id = a.article_id AND a.park_uuid = 100146
LEFT OUTER JOIN cont_users cu ON res.contrib_user_id = cu.id AND cu.park_uuid = 100146
LEFT OUTER JOIN cont_orgs co ON cu.org_id = co.id AND co.park_uuid = 100146
ORDER BY res.exit_time ASC
如何找出问题出在哪里,是什么导致第二个SELECT执行小时?
我正在使用 postgres SQL,服务器版本是 9.6.3 pentaho data-integration
将数据提取到数据库中编辑:
在 运行 两个查询之后 EXPLAIN (ANALYZE, BUFFERS)
最大的显着差异是在这部分:
-> Bitmap Index Scan on longterm_history_park_uuid_idx (cost=0.00..7609.82 rows=352718 width=0) (actual time=492.753..492.753 rows=354537 loops=1)
Index Cond: (park_uuid = 100068)
Buffers: shared read=1238
-> Bitmap Index Scan on longterm_history_park_uuid_idx (cost=0.00..453.11 rows=20890 width=0) (actual time=4.680..4.680 rows=40021 loops=466475)
Index Cond: (park_uuid = 100146)
Buffers: shared hit=65306361 read=139
似乎让第二个 SELECT 变慢的是 loops=466475
而不是第一个 SELECT 造成的 loops=1
。但我不知道这意味着什么或如何解决它..
编辑2:
我找到了可以在线分享计划的工具,这里是链接:
快速查询:https://explain.depesz.com/s/oYQLB
慢查询:https://explain.depesz.com/s/uOtf
慢速查询执行得很快,而提取已关闭:https://explain.depesz.com/s/4h4F
问题已解决。
在许多基于网络的工具的帮助下学习如何阅读 EXPLAIN ANALYZE
以图形化显示它之后,我注意到第二个(较慢)select 正在执行大量循环并且优化器期望更少实际要返回的行数 returns.
这是优化器计算所基于的错误数据的迹象。为了解决它,我在整个数据库上有 运行 VACUUM ANALYZE
。
结果是性能显着提高,查询执行时间缩短了从 4265437.080 毫秒 到 547.202 毫秒