Postgres 8.4.4(Win7 x64 上的 x32)小表上的更新速度非常慢

2023-12-29

我有一个非常简单的更新语句:

UPDATE W SET state='thing'
WHERE state NOT IN ('this','that') AND losttime < CURRENT_TIMESTAMP;

表 W 只有 90 行,每行的丢失时间和状态列大约每 10s 秒更新一次。有状态和损失时间的索引(以及主索引)。

我注意到大型数据库(即其他表有很多条目,而不是表 W)在一段时间内,查询变得越来越慢。运行了48小时后,我通过在PqAdminIII的查询窗口中运行来计时,执行了17分钟!

我在另一个表上有一个类似的查询,显示了同样的问题:

UPDATE H SET release='1' 
WHERE a NOT IN (SELECT id from A WHERE state!='done') AND release!='1';

H 没有任何索引,但我尝试在 H(release) 上放置和删除索引,而行为没有改变。在数据库运行 48 小时且表 H 有约 10 万行之后,此查询需要 27 分钟。 Postgres 服务器在查询期间将有一个完全固定的线程(100% CPU 利用率),因此看起来不会出现任何网络、磁盘等争用。

因此,从广义上讲,我看到的行为是我的数据库按预期运行了大约 5 分钟,然后随着与基本维护相关的 UPDATE 命令开始运行越来越长的时间,一切逐渐停止。到第二天,需要一个小时来完成一个简单的维护周期(少量更新),该周期一开始运行约 100 毫秒。在我看来,很明显,性能下降与数据库中的信息量呈超线性关系——可能是 N^2 或类似的信息量。

Autovacuum 使用默认值。我(再次)通读了手册,但没有看到任何让我惊讶的内容。

我在这里摸不着头脑。我在 9.0.1 和 9.0.2 发行说明中没有看到任何似乎相关的错误修复。谁能帮助我理解发生了什么?谢谢,米

-x-x-x-x-

好吧,我这里可能有两个问题。

现在第一个更新似乎运行得很快。不确定发生了什么,所以我将继续假设我需要更频繁地运行 VACUUM / ANALYZE 或某种组合 - 比如每分钟左右。我真的很想知道为什么 autovacuum 不为我做这件事。

第二次更新继续缓慢运行。查询计划表明索引没有得到有效使用,并且发生了 80k*30k 交叉,这可能是我观察到的超线性运行时的原因。 (大家同意这个规划的解读吗?)

我可以将 UPDATE 转换为 SELECT:

SELECT * from H
where a not in (SELECT id from A where state='done') AND release!='1';

具有相似的运行时间(27 分钟)。

如果我不信任 postgres 优化器并执行以下操作:

WITH r as (select id from A where state='done')
SELECT a from H 
JOIN on H.a=r.id 
WHERE H.released='0';

那么查询将在大约 500 毫秒内运行。

我如何将这些知识转化为以可接受的速度运行的更新? 我的尝试:

UPDATE H SET release='1'
FROM A
where A.state!='done' AND release!='1' AND A.id=H.a;

运行时间约为 140 秒,速度更快,但仍然非常非常慢。

从这里我可以去哪里?

-x-x-x-x-

VACUUM ANALYZE 已作为“日常维护”的一部分添加,其中应用程序将大约每分钟左右运行一次,独立于任何正在运行的 autovacuum。

另外,重写第二个查询以消除已知的缓慢 NOT IN 子句,将其替换为“左反半连接”(嗯?)

UPDATE H SET release='1' 
WHERE release='0' AND NOT EXISTS (SELECT * FROM A WHERE id=H.a AND state!='done');

PostgreSQL实施MVCC.

这意味着每次进行更新时,都会创建行的新副本,并将旧副本标记为已删除(但并未物理删除)。

这会减慢查询速度。

你应该跑VACUUM及时。

PostgreSQL 8.4.4 runs autovacuum守护进程来执行此操作,但它可能会对您的安装产生一些问题。

当你跑步时情况是否有所改善VACUUM手动?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Postgres 8.4.4(Win7 x64 上的 x32)小表上的更新速度非常慢 的相关文章

  • WHERE NOT EXIST 附近的语法错误

    我在堆栈中搜索 但没有一个达到最终答案 我的查询是这样的 INSERT INTO user username frequence autoSend VALUES feri2 3 1 WHERE NOT EXISTS SELECT FROM
  • 更改mysql数据库表中的日期格式

    大家早上好 只是一个简单的问题 在我现有的 MySql 数据库中 我几乎没有包含日期 的列 目前这些是年 月 日格式 但现在我需要将其全部更改为年 月 日格式 我试过了select date format curdate d m Y 但它不
  • SQL查询查找具有特定数量关联的行

    使用 Postgres 我有一个架构conversations and conversationUsers Each conversation有很多conversationUsers 我希望能够找到具有确切指定数量的对话conversati
  • 将DataTable批量插入postgreSQL表中

    在 SQL 中 我们执行类似的操作来批量插入数据表 SqlBulkCopy copy new SqlBulkCopy sqlCon copy DestinationTableName strDestinationTable copy Wri
  • 可以有一个带有可变列的表吗?

    这可能是一个愚蠢的问题 但这里是 是否可以创建一个能够包含具有可变列数和自定义列名称的行的动态表 我浏览过 EAV 建模 但看起来很沉重 现实生活中的例子可能是这样的 假设我有一个客户登记册 但每个客户可能需要输入不同的信息 根据您要输入的
  • 如果 Oracle SQL 中存在视图,则删除视图[重复]

    这个问题在这里已经有答案了 我是 Oracle 数据库系统的新手 Oracle 12c 中以下 SQL 语句的等效项是什么 DROP VIEW IF EXIST
  • SELECT 在 PL/pgSQL 函数中引发异常

    我想在函数内实现循环 但收到此错误 ERROR 查询没有结果数据的目标 代码 CREATE OR REPLACE FUNCTION my function ill int ndx bigint RETURNS int AS DECLARE
  • 向带有检查约束 SQL 的表添加列

    我想向表中添加一列 然后添加一个检查约束以确保其大于 0 我似乎无法让它在 oracle sl Developer 中运行 Alter TABLE store101 add column Base salary Number 7 2 con
  • 是否可以从子查询中获取多个值?

    有没有办法让子查询在oracle db中返回多列 我知道这个特定的sql会导致错误 但它很好地总结了我想要的 select a x select b y b z from b where b v a v from a 我想要这样的结果 a
  • Django 独特的不工作

    我在从查询中过滤掉重复项时遇到问题 我正在使用 Django 1 4 和 Postgres 8 4 13 我在我的模型对象上使用这个查询 它是一个 jquery 自动完成 term request GET get term field re
  • 具有不同组合的产品和产品包的数据库模型

    您将如何设计数据库来实现此功能 考虑一个场景 我们想要创建一个产品关系 封装 假设我们创建一个产品表 prod id prod name prod fee 1 prepaid A 19 usd 2 prepaid B 29 usd 3 pr
  • SQL查询json字典数据

    我的表中的 CLOB 字段包含 JSON 如下所示 a value1 b value2 c value3 我正在尝试编写一个 SQL 查询来返回一个包含键和值字段的表 如下所示 key value a value1 b value2 c v
  • Django 和 PostgreSQL - 值对于类型字符变化来说太长(512)

    我正在从测试 SQLite 数据库迁移到 PostgreSQL 数据库 我有一个插入到数据库中的示例对象 它在 SQLite 上工作 但在 PostgreSQL 中给我一个错误 代码片段是 car CarItem objects creat
  • 如何确定层级组织中的权限?

    我正在尝试创建高性能逻辑来确定分层组织内的权限 员工被分配到一个或多个单位 单元是分层的 理论上 无限深度 实际上不超过 6 层 例如 员工Jane可能是Supervisor of the Accounts Receivable单元 的子单
  • 如何将今天的日期返回到 Oracle 中的变量

    我想做这个 DECLARE today as smalldatetime SELECT today GetDate 但我需要一个oracle翻译 甲骨文使用SYSDATE 还有 ANSI 标准CURRENT TIMESTAMP 除其他外 S
  • PostgreSQL函数中sql语言和plpgsql语言的区别

    我很新数据库开发所以我对下面的例子有一些疑问 函数 f1 语言 SQL create or replace function f1 istr varchar returns text as select hello varchar istr
  • MYSQL:如何在同一查询中联接两个表,两次引用同一个表

    我有两张桌子 我正在尝试将下面的示例两个表与表 1 引用表 2 两次结合起来 例如 如果我查看表 1 组 2 和成员 7 它应该查找表 2 中的 ID 并给出输出 Group Members Name Name 2 7 Blue Dog T
  • 基本的多对多sql选择查询

    我认为这应该很容易 但它却在逃避我 我的帐户和帐户组之间存在多对多关系 一个帐户可以位于零个或多个组中 因此我使用标准连接表 Accounts ID BankName AcctNumber Balance AccountGroups ID
  • 默认情况下在sql日期时间列中插入null/空值

    如何在 SQL Server 中创建一个表 默认日期时间为空 而不是1900 01 01 00 00 00 000我得到了 我的意思是 如果没有插入值 则默认值应该为 null 空等 如果没有插入值 默认值应该是null empty 在表定
  • 使用函数的 SQL 查询 - 如何获取列表的最大计数

    如何查询 MAXIMUM COUNT 交易次数 我的代码如下 SELECT customer id COUNT customer id FROM rental GROUP BY customer id HAVING MAX COUNT cu

随机推荐