Postgres - UPDATE随着时间的推移变慢

时间:2014-10-30 20:52:53

标签: php postgresql postgresql-9.3

我有一个这样的表(更多列,但这些会这样做):

events
+----------+----------------+--------------------+------------------+------------------+---------+  
| event_id | user_ipaddress |   network_userid   |  domain_userid   | user_fingerprint | user_id |  
+----------+----------------+--------------------+------------------+------------------+---------+  
|        1 | 127.0.0.1      | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 |       2199066221 |         |  
|        2 | 127.0.0.1      | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 |       2199066221 |         |  
|        3 | 127.0.0.1      | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 |       2199066221 |         |  
|        4 | 127.0.0.1      | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 |       2199066221 |         |  
+----------+----------------+--------------------+------------------+------------------+---------+

该表包含大约1M条记录。我尝试更新所有记录以设置user_id 我正在使用一个非常简单的PHP脚本。

我在整个表格中使用user_id = NULLSELECT循环遍历每条记录,以根据user_iduser_ipaddress找到现有的network_useriddomain_userid和/或user_fingerprint

如果未找到任何内容,我将生成唯一的user_idUPDATE记录 如果找到匹配项,我将UPDATE与通讯员user_id进行记录。

查询如下所示:

UPDATE events SET user_id = 'abc' WHERE event_id = '1'

SELECT部分超快(~5ms) UPDATE部分快速启动(~10ms),但在几百次更新后变慢(~800ms)。

如果我等待大约10-20分钟,它会再次变快。

我在AWS RDS(db.m1.medium)上运行带有通用SSD存储的PostgreSQL 9.3.3。 我对所有列的索引进行了组合和单独处理。

我玩过FILLFACTOR,目前已设置为70。我试图运行VACUUM FULL events,但我不知道它是否完成(等待超过1小时)。我也试过REINDEX TABLE events

我是唯一使用此服务器的人。

此处是EXPLAIN ANALYZE查询的UPDATE

Update on events  (cost=0.43..8.45 rows=1 width=7479) (actual time=0.118..0.118 rows=0 loops=1)
  ->  Index Scan using events_event_id_idx on events  (cost=0.43..8.45 rows=1 width=7479) (actual time=0.062..0.065 rows=1 loops=1)
        Index Cond: (event_id = '1'::bpchar)
Total runtime: 0.224 ms

关于如何快速保持查询的任何好主意?

3 个答案:

答案 0 :(得分:0)

在10-20分钟内再次变得快速,你会逐步改善吗?

我要检查的事情:

  • 您是否在每次更新时创建新连接并将其保持打开状态?然后它们会超时并在稍后关闭。
  • 系统负载(CPU,内存,IO)在做什么?我确实想知道实例是否可能支持爆发,但我不这么认为。

答案 1 :(得分:0)

我只是猜测, 这是因为你的主键是char而不是int。尝试将主键转换为int并查看结果。

您的解释分析结果显示Index Cond: (event_id = '1'::bpchar)

  1. 主键的最佳选择是整数数据类型,因为整数值的处理速度比字符数据类型值快。在处理之前,需要将字符数据类型(作为主键)转换为ASCII等效值。
  2. 在整数作为主键的情况下,基于主键获取记录将更快,因为这将意味着在单个页面上将存在更多索引记录。所以总搜索时间减少了。连接也会更快。但这将适用于您的查询使用聚簇索引搜索而不扫描,如果只使用一个表。如果扫描没有额外的列将意味着在一个数据页上有更多行。
  3. SQL Index - Difference Between char and int

答案 2 :(得分:0)

我发现问题是由为我的RDS实例选择的文件系统引起的。 我和General Purpose Storage (SSD)一起跑步。它显然有一些I / O限制。因此解决方案是切换存储。现在我正在运行Provisioned IOPS Storage并且性能立即得到改善。

另外一个解决方案可能是坚持General Purpose Storage (SSD)并增加存储空间大小,因为这样会增加I / O限制。

了解更多: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#Concepts.Storage.GeneralSSD

感谢所有回复。感谢@Dan和@ArtemGr将我指向了这个方向。

相关问题