gpt4 book ai didi

database - Postgres : Surprising performance on updates using cursor

转载 作者:搜寻专家 更新时间:2023-10-30 20:12:52 26 4
gpt4 key购买 nike

考虑以下两个 Python 代码示例,它们实现相同但具有显着且令人惊讶的性能差异。

import psycopg2, time

conn = psycopg2.connect("dbname=mydatabase user=postgres")
cur = conn.cursor('cursor_unique_name')
cur2 = conn.cursor()

startTime = time.clock()
cur.execute("SELECT * FROM test for update;")
print ("Finished: SELECT * FROM test for update;: " + str(time.clock() - startTime));
for i in range (100000):
cur.fetchone()
cur2.execute("update test set num = num + 1 where current of cursor_unique_name;")
print ("Finished: update starting commit: " + str(time.clock() - startTime));
conn.commit()
print ("Finished: update : " + str(time.clock() - startTime));

cur2.close()
conn.close()

和:

import psycopg2, time

conn = psycopg2.connect("dbname=mydatabase user=postgres")
cur = conn.cursor('cursor_unique_name')
cur2 = conn.cursor()

startTime = time.clock()
for i in range (100000):
cur2.execute("update test set num = num + 1 where id = " + str(i) + ";")
print ("Finished: update starting commit: " + str(time.clock() - startTime));
conn.commit()
print ("Finished: update : " + str(time.clock() - startTime));

cur2.close()
conn.close()

表测试的创建语句是:

CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);

那个表包含 100000 行和 VACUUM ANALYZE TEST;已运行。

经过多次尝试,我始终如一地得到以下结果。

第一个代码示例:

Finished: SELECT * FROM test for update;: 0.00609304950429
Finished: update starting commit: 37.3272754429
Finished: update : 37.4449708474

第二个代码示例:

Finished: update starting commit: 24.574401185
Finished committing: 24.7331461431

这让我感到非常惊讶,因为我认为这应该是完全相反的,这意味着根据 this,使用游标的更新应该明显更快。回答。

最佳答案

我不认为测试是平衡的——你的第一个代码是从游标中获取数据,然后更新,而第二个代码是盲目地按 ID 更新而不获取数据。我假设第一个代码序列转换为一个 FETCH 命令,然后是 UPDATE- 所以这是两个客户端/服务器命令周转,而不是一个。

(第一段代码也是从锁定表中的每一行开始的——这会将整个表拉入缓冲区缓存——尽管考虑到这一点,我怀疑这实际上会影响性能,但你没有提到它)

此外,我认为对于一个简单的表,通过 ctid 更新(我假设这是 where current of... 的工作方式)和通过主要更新之间没有太大区别key- pkey 更新是一个额外的索引查找,但除非索引很大,否则不会有太大的退化。

像这样更新 100,000 行,我怀疑大部分时间都花在生成额外的元组并将它们插入或附加到表中,而不是定位前一个元组以将其标记为已删除。

关于database - Postgres : Surprising performance on updates using cursor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4776127/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com