【问题标题】:Why is postgres UPDATE function so slow?为什么 postgres UPDATE 功能这么慢?
【发布时间】:2021-08-22 04:01:36
【问题描述】:

我有一个表,其中定义了大约 18 万条记录:

CREATE TABLE table( 
    id text UNIQUE,
    classification text,
    author text,
    date DATE,
    score float,
    transcript text
    )

除了一件事,这里没有什么是太了不起的了。除文字记录列外,所有文本值均小于 200 个字符。成绩单列中的文本通常以数百个字符结束,最多 3MB 的数据。话虽如此,当我在设置新分类的管道中运行以下命令时:

conn = connect()
conn.cursor().execute("UPDATE table SET classification = '%s' WHERE author = '%s'" % (classification, author))

该命令需要非常多的时间。我已经等了 +30 分钟,但我还没有看到这个命令完成。此外,它会暂时锁定这些行,从而冻结查询表的附加 web 应用程序。我不太明白为什么要花这么长时间。

最后,值得注意的是,每个作者在表中的条目少于 40 个。因此,“WHERE”条件所影响的条目不应超过那么多条目。

【问题讨论】:

  • 缺少索引会导致顺序扫描,但是对于这样的小表,这应该是相当快的。唯一的解释是更新被锁阻塞了。对挂起的后端进程的进程ID使用pg_blocking_pids函数。
  • WebApp 到底在等待什么?如果它只是从你的表中读取,那么它不应该受到锁的影响。此外,您应该对任何输入使用绑定变量,而不仅仅是字符串格式 - 这是一个经典的 SQL 注入入口点。
  • 除了已经说过的: 1) 你有没有看过 Postgres 的日志,看看有没有什么有用的东西? 2) sector_long, ticker 真的是想要的变量吗?他们似乎更倾向于股票而不是作者/成绩单。 3) 注意@AndrewSayer 关于绑定变量的建议。

标签: python sql postgresql sql-update


【解决方案1】:

我不知道你的表的相对大小或记录的数量,但如果你还没有在author列上的索引,你可以尝试添加加一:

CREATE INDEX idx ON yourTable (author);

【讨论】:

  • 我认为缺少索引不会导致语句运行超过 30 分钟。我会在另一场比赛中打赌。 ;-)
【解决方案2】:

您可以至少尝试抑制幂等更新,这会导致大量不必要的行版本。


conn.cursor().execute("UPDATE table SET classification = '%s'
WHERE  classification <> '%s'
AND author = '%s'" % (sector_long, sector_long, ticker) )

此外:由于您抱怨此更新锁定了其他进程,因此也可能是其他进程 [b] 锁定了您的更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-15
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 2022-01-09
    • 2017-02-11
    • 2023-04-04
    相关资源
    最近更新 更多