相关疑难解决方法(0)

如何在PostgreSQL中进行大型非阻塞更新?

我想在PostgreSQL中对表进行大量更新,但我不需要在整个操作中维护事务完整性,因为我知道我正在更改的列不会被写入或读取更新.我想知道psql控制台中是否有一种简单的方法可以更快地完成这些类型的操作.

例如,假设我有一个名为"orders"的表,有3500万行,我想这样做:

UPDATE orders SET status = null;
Run Code Online (Sandbox Code Playgroud)

为避免被转移到offtopic讨论,让我们假设3500万列的所有状态值当前都设置为相同(非空)值,从而使索引无用.

此语句的问题是需要很长时间才能生效(仅因为锁定),并且所有更改的行都将被锁定,直到整个更新完成.此更新可能需要5个小时,而类似

UPDATE orders SET status = null WHERE (order_id > 0 and order_id < 1000000);
Run Code Online (Sandbox Code Playgroud)

可能需要1分钟.超过3500万行,执行上述操作并将其分成35块只需要35分钟,节省了4小时25分钟.

我可以用脚本进一步分解它(在这里使用伪代码):

for (i = 0 to 3500) {
  db_operation ("UPDATE orders SET status = null
                 WHERE (order_id >" + (i*1000)"
             + " AND order_id <" + ((i+1)*1000) " +  ")");
}
Run Code Online (Sandbox Code Playgroud)

此操作可能仅在几分钟内完成,而不是35分钟.

所以这归结为我真正的要求.我不想写一个怪异的脚本来分解操作,每次我想做这样一个大的一次性更新.有没有办法在SQL中完成我想要的东西?

postgresql dblink transactions plpgsql sql-update

61
推荐指数
3
解决办法
3万
查看次数

使用SQLAlchemy中的bulk_update_mappings更新具有不同值的多个行

我有两张桌子Foo和Bar.我刚刚x在Bar表中添加了一个新列,它必须使用Foo中的值填充

class Foo(Base):
    __table__ = 'foo'
    id = Column(Integer, primary_key=True)
    x = Column(Integer, nullable=False)

class Bar(Base):
    __table__ = 'bar'
    id = Column(Integer, primary_key=True)
    x = Column(Integer, nullable=False)
    foo_id = Column(Integer, ForeignKey('foo.id'), nullable=False)
Run Code Online (Sandbox Code Playgroud)

一种直接的方法是迭代Bar中的所有行,然后逐个更新它们,但需要很长时间(Foo和Bar中有超过100k行)

for b, foo_x in session.query(Bar, Foo.x).join(Foo, Foo.id==Bar.foo_id):
    b.x = foo_x
session.flush()
Run Code Online (Sandbox Code Playgroud)

现在我想知道这是否是正确的方法 -

mappings = []
for b, foo_x in session.query(Bar, Foo.x).join(Foo, Foo.id==Bar.foo_id):
    info = {'id':b.id, 'x': foo_x}
    mappings.append(info)
session.bulk_update_mappings(Bar, mappings)
Run Code Online (Sandbox Code Playgroud)

那里没有太多的例子bulk_update_mappings.文档建议

所有存在且不属于主键的键都应用于UPDATE语句的SET子句; 必需的主键值应用于WHERE子句.

那么,在这种情况下id将在WHERE子句中使用,然后使用x字典中的值进行更新吧?

python mysql sqlalchemy

16
推荐指数
1
解决办法
5182
查看次数

PostgreSQL在一个包含数组和大量更新的大型表上变慢

我有一个非常大的表(20M记录),它有一个3列索引和一个数组列.数组列每天更新(通过附加新值)所有行.还有插入,但没有更新.

数组中的数据表示对应于三个键的每日测量值,如下所示:[[date_id_1, my_value_for_date_1], [date_id_2, my_value_for_date_2]].它用于绘制这些每日值的图表.假设我希望随着时间的推移可视化键(a,b,c)的值,我这样做SELECT values FROM t WHERE a = my_a AND b = my_b AND c = my_c.然后我使用values数组绘制图形.

更新的性能(每天大量发生一次)随着时间的推移而显着恶化.

使用PostgreSQL 8.3.8.

你能给我一些关于在哪里寻找解决方案的提示吗?它可能是从postgres调整一些参数到甚至移动到另一个数据库(我猜一个非关系数据库更适合这个特定的表,但我没有太多的经验).

postgresql optimization performance

10
推荐指数
1
解决办法
1万
查看次数

如何优化更新每一行的PostgreSQL查询?

我写了一个查询来更新整个表.如何改进此查询以减少时间:

update page_densities set density = round(density - 0.001, 2)
Run Code Online (Sandbox Code Playgroud)

查询成功返回:受影响的行为628391行,执行时间为1754179毫秒(29分钟).

编辑:通过设置工作记忆..

set work_mem = '500MB';
update page_densities set density = round(density - 0.001, 2)
Run Code Online (Sandbox Code Playgroud)

查询成功返回:628391行受影响,731711毫秒(12分钟)执行时间.

sql postgresql performance query-performance

7
推荐指数
1
解决办法
442
查看次数

为什么 postgresql 更新查询有时如此缓慢,即使有索引

我有一个简单的更新查询(foo 列类型是 BOOLEAN(默认为 false)):

update tablename set foo = true where id = 234;
Run Code Online (Sandbox Code Playgroud)

其中“id”设置为(主)键,如果我运行“解释分析”,我得到:

Index Cond: (id = 234)
Total runtime: 0.358 ms
Run Code Online (Sandbox Code Playgroud)

但是,我在慢日志 (pgfouine) 中有很多无法解释的查询,耗时超过 200 秒(?!):

Times executed: 99, Av. duration (s): 70
Run Code Online (Sandbox Code Playgroud)

谁能解释一下,这是什么原因?(表中的 1.5 个 mio 行,postgresql 8.4)

postgresql indexing performance execution

5
推荐指数
1
解决办法
7477
查看次数