我需要製作大量SQL查詢來更新或插入使用Psycopg2的行。沒有其他查詢正在中間運行。阿具有列name
和value
例如具有表:使用Psycopg2優化一系列SQL更新查詢
% Basically models a list of strings and how many times they "appear"
% 'foo' is some random value each time, sometimes repeating
insert into A select ('foo', 0)
where not exists(select 1 from A where name = 'foo' limit 1);
update A set value = value + 1 where name = 'foo';
% ... and many more just like this
這只是一個實例,一種類型的查詢我跑。我也在做其他事情。我不在尋找解決方案,包括重新處理我的SQL查詢。
它真的很慢,Postgres(運行在另一臺服務器上)瓶頸。我已經嘗試了各種各樣的東西來讓它更快。
- 如果我在每次查詢之後犯下這種情況,這種速度令人難以忍受。
- 如果我沒有
connection.commit()
直到最後,它會快一點。這似乎是Psycopg2文檔建議的。 Postgres在磁盤訪問方面仍然存在瓶頸。 - 如果我使用
cursor.mogrify()
而不是cursor.execute()
,將所有查詢存儲在一個大列表中,並將它們最後加入一個大規模查詢(字面上爲";".join(qs)
)並運行它,速度會更快。 Postgres使用100%CPU,這是一個好兆頭,因爲這意味着〜沒有磁盤瓶頸。但是,這有時會導致postgres
進程耗盡我所有的RAM和初始頁錯誤,從而永久地阻礙磁盤訪問,成爲一場災難。我已經使用pgtune將Postgres的所有內存限制設置爲合理的值,但是我猜測Postgres正在分配一堆沒有限制的工作緩衝區並且繼續。 - 我已經嘗試了上述解決方案,除了承諾每100,000個查詢以避免超載服務器,但這不會是一個完美的解決方案。這是我現在所擁有的。這似乎是一個可笑的黑客,並且比我想要的還要慢。
有沒有其他方法我應該嘗試涉及Psycopg2?
忘記我已經在我的處置複製!我正在努力做到這一點。我沒有使用memcached,但我在Python dicts中建立了大量數據(直到RAM變短),將它們複製到臨時表中的數據庫中,然後用一個UPDATE查詢將臨時表與永久表合併在一起。我也有一些更復雜的聚合函數,所以我不得不做一些數學計算如何合併。 – sudo
另外,如果我的數據無法合併,這可能不起作用,可能是因爲某些遞歸函數。例如,如果我保持新值和最後值之間的平均差值......幸運的是,情況並非如此。 – sudo