【问题标题】:Query very long to execute查询执行时间很长
【发布时间】:2014-11-17 22:53:54
【问题描述】:

我正在 2GB RAM VPS 上执行 Postgresql 数据库。

设置如下:

max_connections = 100
work_mem=1MB
shared_buffers=128MB

我正在执行一个包含一百万行的非常简单的查询:

SELECT s.executionTime, g.date, s.name
FROM SimulationStatsGroup g
LEFT JOIN SimulationStats s ON s.group_id = g.id
WHERE g.name = 'general'
ORDER BY g.date DESC

我有 2 张桌子:SimulationStatsGroupSimulationStatsSimulationStatsGroup 包含 1 到 13 个 SimulationStatsSimulationStats 是一个简单的实体,其中包含我的应用程序使用的 executionTime 等数值。每个SimulationStatsGroupSimulationStats 都有一个名称。

这是我得到的EXPLAIN ANALYZEhttp://explain.depesz.com/s/auLK

为什么我的查询执行时间这么长?

【问题讨论】:

  • 原因是“排序方法:外部合并磁盘:140784kB”。尝试为您的会话增加 work_mem 并检查对查询的改进程度。虽然 2GB RAM 对于数据库服务器来说确实很小(我认为 Oracle 会拒绝从那个开始......)
  • 您正在返回超过一百万行。你为什么抱怨执行时间?大部分时间可能只是返回数据(排序没有帮助)。
  • 你有关于 SimulationStats(group_id) 和 SimulationStatsGroup(id) 的索引吗?正如其他人所指出的,无论如何,对一百万条记录进行排序肯定需要时间。
  • 您确定 EXPLAIN ANALYZE 的结果来自上述查询吗? ORDER BY 看起来有点不同。 g.date 上的索引可以帮助加快排序
  • @a_horse_with_no_name 10MB work_mem 仍然需要很长时间

标签: sql postgresql


【解决方案1】:

在 SimulationStats(group_id) 和 SimulationStatsGroup(id) 上创建索引。

【讨论】:

  • 谢谢,它改进了此查询和其他查询(使用其他索引)的执行时间。对于某些查询,我的时间缩短了 200 倍
【解决方案2】:

在解释计划的排序(步骤#2)中,看起来数据库要么拖着未引用的列(不是最佳的)和/或按它们排序(哎哟)。不过老实说,我不在 Postgres 上工作,所以这只是一个有根据的猜测。数据库引擎可能不够聪明,无法在流程早期丢弃未引用的列。我会尝试使用此 SQL 来推动数据库引擎在进行排序之前丢弃未引用的列,您可能会看到运行时的显着改进:

SELECT s.executionTime, g.date, s.name
FROM ( select id, date from SimulationStatsGroup WHERE g.name = 'general') as g
LEFT JOIN ( select s.group_id, s.name, s.executionTime from SimulationStats ) as s 
       ON s.group_id = g.id   
ORDER BY g.date DESC

如果此版本显示运行时改进,请运行另一个解释,如果排序步骤中的列列表较少,请告诉我们。如果是这样,我的预感很可能是正确的。如果正确,希望 Postgres 开发人员会注意到并尝试在未来的版本中为我们丢弃未引用的列,而不是我们手动对其进行编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 2018-07-06
    • 2014-07-07
    • 1970-01-01
    • 2023-03-12
    • 2019-07-28
    相关资源
    最近更新 更多