标签: update

提高 PostgreSQL 数据仓库 (RDS) 中的更新性能

我正在使用 Amazon RDS 上托管的 Postgres 数据仓库。当尝试从同一数据库中的另一个表更新事实表的一列(2500 万行)时,查询需要几天时间才能运行。为什么会发生这种情况,我该如何提高这种性能?我知道 PG 是为 OLTP 而设计的,而不是 OLAP,但是在这个表上选择查询性能通常相当不错。

有问题的查询如下所示:

UPDATE a
SET a.value = b.value
FROM b
WHERE a.id = b.id
Run Code Online (Sandbox Code Playgroud)

b是不同架构中的临时表,但与a. 两个表在 上都有主键idvalue列上没有索引或约束。有依赖于表a但没有外键的视图

我在 RDS 上使用 PG 9.5。具有 256 GB 存储空间的通用型 (SSD),因此在用尽我们最初的突发 IOPS 后,我的 IOPS 应该会略低于 800。

IOPS 节流真的是这里的问题吗?在观看查询运行时,我看到写入性能约为 400 IOPS,读取性能类似。25,000,000 行 / 400 IOPS = 17 小时,但此查询的运行时间比 24 小时长得多(大约 30 小时后取消以尝试进行调整)。同一个表上还有其他一些定期更新流量,但是当我看到这个查询花费了多长时间时,我在大约 20 小时时停止了它。

我想知道我的一般更新方法是否错误,或者是否有使用 postgres 操作数据仓库(OLAP 工作负载)的一般建议。我能否通过放弃 RDS 并在 EC2 上运行 PG 来获得更好的性能?

更新:受回复和评论的启发,我对 45k …

postgresql performance data-warehouse update amazon-rds postgresql-performance

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

如何在 Postgres 中一次更新多个表?

我有几个结构完全相同的表,我需要更新所有表中的值。

为此,我尝试构建以下脚本:

DO
$do$
DECLARE
  i pg_tables%rowtype;
BEGIN
FOR i IN SELECT * FROM pg_catalog.pg_tables where schemaname like 'public' and tablename like '%_knex_migrations'
LOOP
    UPDATE i.tablename SET name = replace(name, '.js', '.ts');
END LOOP;
END
$do$;
Run Code Online (Sandbox Code Playgroud)

我可以看到它i.tablename具有正确的值(我插入到 tmp 表中进行检查),但更新失败。

name: error
length: 223
severity: ERROR
code: 42P01
internalPosition: 8
internalQuery: UPDATE i."tablename" SET name = replace(name, '.js', '.ts')
where: PL/pgSQL function inline_code_block line 7 at SQL statement
file: parse_relation.c
line: 965
routine: parserOpenTable
Run Code Online (Sandbox Code Playgroud)

只是声明i.tablename上的插件UPDATE不起作用。 …

postgresql dynamic-sql plpgsql update

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

当您使用更长的字符串更新 VARCHAR 单元格时会发生什么?

VARCHAR(32)假设我在 mySQL 数据库中有一个类型的列。

9 月 1 日,我决定存储该字符串"tea",但 9 月 2 日,我决定将其更新为"coffee".

显然,如果该表中的所有记录都相互挤压,并且我们尝试将一条记录加长 3 个字节,那么该记录之后出现的所有记录都需要向下移动 3 个字节。当然,这是荒谬的;任何 DBMS 都不可能转移数千个可能的条目。

那么mySQL 在这种情况下到底会做什么呢?对于 TEXT 和 BLOB 类型,它的行为方式是否相同?

编辑: 一天后读完这篇文章后,我意识到这个问题相当模糊。这是一个我希望能够澄清问题的例子:

假设我有一个表,fav_drinks有两列:

  • user_id,这是一个INTEGER
  • drink,这是一个VARCHAR(32)

假设这个表在内存中是这样存储的:

[1,"juice",2,"tea",3,"soda",4,"hot chocolate"]
Run Code Online (Sandbox Code Playgroud)

也就是说,所有记录都按顺序存储。如果我们需要将用户 2 最喜欢的饮料从 更新为"tea""coffee"理论上我们需要将用户 3 和 4 的条目下移。当然,我不认为这在真实的数据库中会发生。

那么,重申一下这个问题,mySQL 如何管理一个表条目突然需要更多内存的这种特定情况?

mysql varchar update

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

SQL Server 并发插入和删除

来自:SQL Server 2014 并发输入问题

后续问题:
我们如何在并行、多线程环境中删除和重新插入行,同时避免竞争条件、死锁等?我们仍然使用 ( UPDLOCK, SERIALIZABLE) 或其他锁吗?

我们有两个表:OrderOrderLineDetail。表Order是存储一般信息的父级;和OrderLineDetail是子表,因为订单有多个明细行项目。

订单可以更新,所以我们首先检查OrderId表中是否存在,并相应地插入或更新。

由于客户修改、线路问题、服务器繁忙等,订单文件可以多次发送。我们有一个时间Lastfiledatetime栏。如果传入的时间戳较旧,则对表没有影响。

对于OrderLineDetail表,有时我们的文件中没有自然键或代理键,因此我们删除所有子OrderLineDetail项,然后重新填充(这是一个较旧的遗留系统的 xml 文件)。

Create Table Orders 
(OrderId bigint primary key,  -- this is in xml files
 Lastfiledatetime datetime null
)

Create Table OrderLineDetail 
(OrderLineDetailid bigint primary key identity(1,1),  -- this is Not in the xml files
 OrderLineDescription varchar(50), 
 OrderLineQuantity int, 
 OrderId bigint foreign key references Orders(OrderId),
 Lastfiledatetime datetime
) …
Run Code Online (Sandbox Code Playgroud)

database-design sql-server concurrency ddl update

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

如何通过根据条件添加“1”来更新列值?

我有下表fields

+----------+---------+-----------------+-------------+---------+--------------+---------------+-----------+------------------------------+-------------+------------------+
| field_id | form_id | form_section_id | is_required | grid_id | is_base_grid | field_type_id | field_seq |          field_name          | field_class | field_class_data |
+----------+---------+-----------------+-------------+---------+--------------+---------------+-----------+------------------------------+-------------+------------------+
|   220481 |    9926 | NULL            |           0 | NULL    | NULL         |             4 |        28 | Test                         | NULL        | NULL             |
|   281863 |    9926 | NULL            |           0 | NULL    | NULL         |            10 |        29 | insert after yes no question | NULL        | NULL             |
|   220496 …
Run Code Online (Sandbox Code Playgroud)

sql-server update sql-server-2016

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

查询计划问题

我创建了一个 varbinary 哈希来检查 2 个表之间的更改。

这是执行计划,我对索引有点困惑,或者确实有更好的编写方式。 https://www.brentozar.com/pastetheplan/?id=HkHmqoczm

连接中的 2 列是目标中的 PK,并且在源中具有非聚集索引。困扰我的一点是排序导致的 tempdb 溢出。

sql-server query execution-plan update

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

为什么在这个 UPDATE 计划中有一个聚合?

鉴于这种

declare @Data table (id int, fact char(1));
declare @Summary table (id int, collected varchar(99));

insert @Data(id, fact)
values
    (1, 'a'),
    (1, 'b'),
    (2, 'c'),
    (2, 'd'),
    (2, 'e');

-- Form a list of unique id values
insert @Summary(id, collected) select distinct id, '' from @Data;

-- Accumulate the fact values into collected
update s
set collected = collected + d.fact
from @Summary as s
inner join @Data as d
    on d.id = s.id;

select * from @Summary;
Run Code Online (Sandbox Code Playgroud)

我曾预料

id …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan update

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

使用 NOEXPAND 更新索引视图

我先说这是来自 Stack Overflow 上一个未回答问题的交叉帖子
我这样做并不是为了获得对这个问题的更多看法,我希望 DBA 社区分享他们对这是否可能是 SQL Server 中的错误的看法。我认为 SO 社区没有专业知识来决定这一点,所以我在这里重新发布。


假设我有一个 table T,并且我有一个索引视图V

CREATE TABLE dbo.T (id int PRIMARY KEY, b bit NOT NULL, txt varchar(20));
GO
CREATE VIEW dbo.V
WITH SCHEMABINDING AS
  SELECT T.Id, T.txt
  FROM dbo.T AS T
  WHERE T.b = 1;
GO
CREATE UNIQUE CLUSTERED INDEX idx_V ON dbo.V (Id);
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中,它基本上只是一个过滤索引,但它也可以有连接等。

我现在想在Twhere 中选择一些行,这里b = 1的过滤视图非常有用,我在标准上所以必须使用NOEXPAND(或者它对于视图匹配来说太复杂了):

SELECT Id, txt
FROM V WITH (NOEXPAND);
Run Code Online (Sandbox Code Playgroud)

这很好用。

现在我想将这些行更新为某个值。该视图符合可更新条件,因此我可以执行以下操作: …

sql-server t-sql materialized-view update

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

PostgreSQL 更新加入与 SQL Server 更新加入

我最近开始将个人项目从 Microsoft SQL Server 转换为 PostgreSQL,我对UPDATE JOIN在两个表之间执行时遇到的糟糕性能感到惊讶。

假设它们看起来像:

CREATE TABLE foo (
  id INTEGER NOT NULL PRIMARY KEY,
  bar INTEGER NULL
);

CREATE TABLE foo2 (
  id INTEGER NOT NULL PRIMARY KEY,
  bar INTEGER NULL
);
Run Code Online (Sandbox Code Playgroud)

在 T-SQL 中,我会使用这样的连接来进行更新:

UPDATE foo
SET bar = t2.bar
FROM foo t1
JOIN foo2 t2
ON t1.id = t2.id;
Run Code Online (Sandbox Code Playgroud)

但是在 Postgres 中运行,查询速度非常慢。

如果我将其更改为:

UPDATE foo
SET bar = t2.bar
FROM foo2 t2
WHERE foo.id = t2.id;
Run Code Online (Sandbox Code Playgroud)

这不是问题。

我知道语法是不同的,但我希望查询优化器能在同一个球场上解决一些问题。相反,事情变得疯狂。除了语法差异之外,我看不到的两个查询之间是否存在细微差别?

解释计划

Update on foo …
Run Code Online (Sandbox Code Playgroud)

postgresql join sql-server update

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

使用 SET @Variable = Field= @Variable + 1 在堆上的意外更新结果,用聚集索引修复

我只是想了解为什么会发生这种情况,而我的 Google 搜索失败了。我们使用的是 SQL Server 2016 SP1。

这是这种情况:供应商表通过跟踪每个表的当前值来管理 ID。如果您正在执行插入操作,则可以调用一个函数来返回一个 ID 块。

因此,我们通过使用从真实表中选择来设置临时表select into(我们正在克隆一组数据,以使用不同的属性集重新插入)。

然后我们调用该函数并获取记录数的新 id(它只返回最大 ID,因此我们进行一些数学运算以获取下一个 id)。

然后我们更新表格:

update #temp set @nextId = Id = @nextId + 1
Run Code Online (Sandbox Code Playgroud)

期望它会为每条记录递增 1 并设置 id。

相反,为每 4 条记录设置相同的 ID,然后它会递增,接下来的 4 条会得到下一个 id,等等。为什么每 4 条记录?什么地方出了错?

结果

更有趣的是,如果我们在表上放置一个聚集索引,一切都会正常进行。

我确定这与表是堆有关……但不知道为什么。

链接到计划

sql-server clustered-index heap update

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