【问题标题】:2 almost Identical selects on same DB table takes vastly different time to execute在同一个数据库表上进行 2 次几乎相同的选择需要大不相同的时间来执行
【发布时间】:2017-12-22 08:54:25
【问题描述】:

对于圣诞节,我有一个问题我真的很努力寻找如何处理的线索..

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

现在我有一个 SELECT,供 pentaho 报告在此报告数据库中的同一个数据库表上执行。虽然一个 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 = 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 数据集成将数据提取到数据库中


编辑:

通过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 dne。但我不知道这意味着什么或如何解决它..


编辑2:

我找到了可以在线分享计划的工具,这里是链接:

快速查询:https://explain.depesz.com/s/oYQLB

慢查询:https://explain.depesz.com/s/uOtf

在 fetches 关闭时快速执行慢查询:https://explain.depesz.com/s/4h4F

【问题讨论】:

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

标签: sql linux database postgresql pentaho-data-integration


【解决方案1】:

问题已解决。

在学习如何阅读 EXPLAIN ANALYZE 并借助大量基于 Web 的工具以图形方式显示它之后,我注意到第二个(SLOWER)选择正在执行大量循环,并且优化器期望返回的行数少于实际返回的行数.

这是优化器计算所基于的错误数据的标志。为了解决这个问题,我在整个数据库上运行了VACUUM ANALYZE

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

【讨论】:

    猜你喜欢
    • 2020-08-30
    • 2011-01-27
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多