我有两个主要表:帐户和项目。一个帐户可以有多个项目。也就是说,我的项目表有超过4M的记录。
问题是我有一个超过41k项的帐户,我想将其项目的deleted_at
列更新为实际时间戳,但我的查询未完成。我收到一条错误消息,指出由于超时而无法完成查询。
这是我正在尝试运行的查询:
UPDATE "Item" SET "deleted_at"='2015-12-23 19:10:00' WHERE account_id = 859;
即使在较小的帐户中,由于数据库中存储了大量项目,因此查询需要很长时间才能完成。
但是,如果我选择所有帐户的项目,查询将在近3秒内完成,在我看来,这是可以接受的。所以,我想象问题可能与UPDATE
本身有关。
那么,我该怎么做才能更新这些记录?
我现在面临的另一个问题是项目表的增长(此时,如果我运行SELECT count(*) from "Item"
,我也会超时)。
我需要知道我该怎么做以及如何优化数据库才能做到这一点,并处理记录数量的增加。
谢谢!
编辑#1:
我在更新正在运行的SELECT relation::regclass, * FROM pg_locks WHERE NOT GRANTED;
时检查了pg_locks,但没有显示任何内容。所以,我假设查询没有等待任何锁定。
我尝试为Item和Account表运行EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM ...
。我的实时数据库中的Item查询从未完成(再次超时...),因此我在本地转储中运行它。这些是我得到的结果。
Account - Remote database
---------------------------
"QUERY PLAN"
"Seq Scan on \"Account\" (cost=0.00..532.45 rows=4245 width=539) (actual time=0.032..8.919 rows=4247 loops=1)"
" Buffers: shared hit=97 read=393 written=31"
"Planning time: 0.063 ms"
"Execution time: 12.849 ms"
Item - Local dump
---------------------------
"QUERY PLAN"
"Seq Scan on \"Item\" (cost=0.00..869926.62 rows=19644062 width=233 (actual time=8.408..11660.646 rows=19492549 loops=1)"
" Buffers: shared hit=4171 read=669315"
"Planning time: 0.323 ms"
"Execution time: 14055.453 ms"
正如您所要求的,这是我的表结构:
帐户(id,account_name,uID,cloud_id,created_at,updated_at,user_id,deleted_at)
帐户索引:无
帐户限制:id - >主键,user_id - >外键,cloud_id - >外键
项目(id,name,is_favorite,last_modified,item_id,parent_id,item_size,item_type,read_only,mime_type,created_at,updated_at,deleted_at,cloud_item_id,account_id)
项目限制:id - >主键,account_id - >外键,item_id - >独特
项目索引:account_id,cloud_item_id,created_at,item_name,parent_id,item_id。
我创建了这个索引,因为这些是我主要用来搜索项目的字段。我不知道这是否也是问题的一部分。
所有表格的所有外键都将onUpdate
设置为CASCADE
,将onDelete
设置为SET NULL
。
此外,这两个表中没有删除任何内容。如果您删除了某个帐户或某个项目,我们会将deleted_at
时间戳设置为实际的时间戳。
表格大小(数字或记录): 帐户:4.247,项目:19.492.549(是的,比我最初告诉你的要多得多)。
另一个有趣的事实是,如果我将我在Azure Virual Machine中运行的实时数据库导入到我的机器中,尽管查询需要很长时间,但它完成了。另一方面,在远程数据库中,我甚至无法计算我存储的项目总数。我的本地机器有一个SSD,vm没有。
VM规格:2核,7 GB RAM,1个数据磁盘,最大IOPS 500。
我正在使用Postgres 9.4。
如果您需要更多信息,请告诉我,我很乐意为您提供。
谢谢!