Python psycopg2 - 选择查询随机花费很长时间

Posted

技术标签:

【中文标题】Python psycopg2 - 选择查询随机花费很长时间【英文标题】:Python psycopg2 - Select query takes long time randomly 【发布时间】:2021-12-30 07:24:44 【问题描述】:

我正在处理一项任务,我需要遍历一堆 ID 并从 PgSQL 服务器 12.7 获取相关数据。 我在 python 中添加了一个 for 循环以及使用 psycopg2 2.9.1 版连接到数据库的所有相关代码

connectStr = "dbname='dbName' user='postgres' password='test123' host='localhost'"
conn = psycopg2.connect(connectStr)
dataList = []
with conn.cursor() as newCursor:
  query = "select * from myTable where ID = <ID in the loop>"
  newCursor.execute(query)
  for row in newCursor:
     dataList.append(row[0])

此代码对于某些 ID 运行良好,但随后进入一个随机 ID 的长时间运行状态(超过 2 小时)。这个卡住的ID在取出单独运行时,30秒执行。 (每个 ID 执行的平均时间约为 30 秒)

我还使用查询检查了数据库级锁和pg_stat_activity 表 -

SELECT
activity.pid,
activity.usename,
activity.query,
blocking.pid AS blocking_id,
blocking.query AS blocking_query
FROM pg_stat_activity AS activity
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(activity.pid));

但就目前而言,它只是“长时间运行”的查询,而不是“阻塞”的查询。

使用查询 select * from pg_stat_activity where state = 'active' 我可以在 wait_event 列中看到“BufFileRead”几毫秒,然后它会返回 Null。

我在每次循环后明确关闭所有游标和连接,但它仍然卡在“随机”ID上。

有人可以在这里指导我如何解决这个问题吗?我可以根据需要分享更多信息。

谢谢,

卫生巾

【问题讨论】:

您是否为列 ID 添加了索引? B-Tree 索引或哈希索引可能会加快 SELECT 语句的速度。 @raviadhikari - 是的,已经为该列添加了 B-Tree 索引。这里的主要问题是查询在某些 ID 运行良好后随机卡住。 使用这个 - "select * from pg_stat_activity where state = 'active'" 我可以在 wait_event 中看到 "BuffFileRead" 几毫秒,它会返回 Null。 当您使用循环时,您能否确定哪个查询卡住了 你的 python 代码在执行过程中没有显示任何循环,只在它下面显示。 【参考方案1】:

使用for 循环查询数据库几乎总是一个坏主意。它会给数据库带来高负载,响应速度会慢得多。在大多数情况下,时间是不可预测的,就像您的情况一样。

优化查询的一种方法是:

SELECT * FROM TABLE WHERE ID IN(1, 2, 3, 4)

您可以在执行查询之前先创建 ID 数组。您在此处运行单个查询,而不是 N 查询数。它将执行得更快。因此,数据库性能的基本经验法则是,以尽可能少的查询量获取数据。 对于您的情况,您可以通过单个查询获取数据。如果您在N 迭代中运行N 数量的查询,您的数据库性能将受到严重影响。此外,ID 通常被视为主键,因此我假设如果 ID 不是主键,则将其设为主键或添加索引。

【讨论】:

以上是关于Python psycopg2 - 选择查询随机花费很长时间的主要内容,如果未能解决你的问题,请参考以下文章

Psycopg2 - 返回前 1000 个结果并随机选择一个

Psycopg2 是不是允许使用 Python 在 redshift 上运行 udf create 查询?

Postgres Python 查询导入 pg 与导入 psycopg2

Psycopg2 SQL 语句在查询生成器中工作,但不是在 Python 中

使用 psycopg2 在 python 中执行查询时出现“ProgrammingError:在或附近出现语法错误”

使用 psycopg2 从 python 3 使用 redshift 进行慢速更新查询