Sql 在同一个DB表上执行2次几乎相同的选择所需的时间大不相同

Sql 在同一个DB表上执行2次几乎相同的选择所需的时间大不相同,sql,linux,database,postgresql,pentaho-data-integration,Sql,Linux,Database,Postgresql,Pentaho Data Integration,圣诞节的时候,我有一个问题,我真的很想找到一些线索来解决 我有一个报告数据库,它由来自卫星数据库的数据填充,在许多较小的机器上。每个卫星数据库每20分钟平均执行一次数据提取。他们使用相同的脚本。然而,它们安装在不同的装置上,分布在全国各地 现在我有一个SELECT,pentaho reporting使用它在这个report DB中的同一个DB表上执行。虽然一个SELECT需要毫秒才能执行,但另一个则需要数小时。它们都在同一个表上执行,在同一个数据库中,在同一个硬件上运行 快速一: 慢的人: SE

圣诞节的时候,我有一个问题,我真的很想找到一些线索来解决

我有一个报告数据库,它由来自卫星数据库的数据填充,在许多较小的机器上。每个卫星数据库每20分钟平均执行一次数据提取。他们使用相同的脚本。然而,它们安装在不同的装置上,分布在全国各地

现在我有一个SELECT,pentaho reporting使用它在这个report DB中的同一个DB表上执行。虽然一个SELECT需要毫秒才能执行,但另一个则需要数小时。它们都在同一个表上执行,在同一个数据库中,在同一个硬件上运行

快速一:

慢的人:

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
如何找出问题所在,是什么导致第二次选择在几个小时内执行

我使用的是PostgresSQL,服务器版本是9.6.3 通过pentaho数据集成将数据提取到数据库中


编辑:

通过
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
似乎第二次选择较慢的是
loops=466475
,而不是第一次选择的
loops=1
dne。但我不知道这意味着什么,也不知道如何修复它


编辑2:

我发现tootl可以在线共享计划,以下是链接:

快速查询:

慢速查询:


慢速查询在回迁关闭时快速执行:

问题已解决

在学习了如何通过大量基于web的工具以图形方式显示它来阅读
EXPLAIN ANALYZE
之后,我注意到second(较慢)select执行了大量循环,优化器希望返回的行比实际返回的行少

这是优化器基于计算的错误数据的迹象。为了解决这个问题,我对整个数据库运行了
VACUUM ANALYZE


结果是性能显著提高,查询执行时间从4265437.080毫秒缩短到547.202毫秒。

请为两个查询发布
解释(分析,缓冲)
输出。如果您告诉我们查询之间的区别而不是让我们搜索,那也很好。两个查询没有区别,唯一的区别是
park_uuid
value,日期和其他参数都相同。我知道,如果不访问完整的数据集,您就没有太多的选项可以提供帮助。我更喜欢询问如何分析问题的建议。这可能是一个参数嗅探问题吗?如果唯一的区别是park_uuid的值,那么作为一个开始,我将为您正在搜索的每个park_uuid运行每个表中的行计数。我还将尝试通过命令行工具psql进行查询,以消除Pentaho可能正在做的任何事情。也许你已经这么做了?我认为查询优化器会处理这个问题,但我会将文本值放入一次,并使用连接将其与其他表匹配,以帮助优化器完成其工作。
                                           ->  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