我不明白 Craig Ringer 在评论时的意思:
如果插入事务回滚,此解决方案可能会丢失更新;没有强制执行 UPDATE 影响任何行的检查。
在/sf/answers/609160401/ 上。请提供一个示例事件序列(例如,线程 1 执行 X,线程 2 执行 Y)以演示丢失更新是如何发生的。
我正在尝试使用新的 Postgresql 9.5 upsert 功能。但出于某种原因,我的查询说约束不存在(当它存在时)。
我的查询是这样的
INSERT INTO journals (ext_ids, title) VALUES ('{"nlmid": "000"}', 'blah')
ON CONFLICT ON CONSTRAINT idx_nlmid_journal DO NOTHING;
Run Code Online (Sandbox Code Playgroud)
哪里idx_nlmid_journal是这样创造的jsonb领域唯一索引
CREATE UNIQUE INDEX idx_nlmid_journal ON public.journals ((ext_ids ->> 'nlmid'::text));
Run Code Online (Sandbox Code Playgroud)
我得到错误
ERROR: constraint "idx_nlmid_journal" for table "journals" does not exist
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
有一张这样的表:
CREATE TABLE aggregated_master (
"user" BIGINT,
type TEXT,
date TIMESTAMP,
operations BIGINT,
amount NUMERIC,
PRIMARY KEY ( "user", type, date )
);
Run Code Online (Sandbox Code Playgroud)
这张表是很多分区继承的主表。分区由 DATE 字段中的 MONTH 完成。例如:2017 年 8 月的分区将是 agg_201708,它的 PK 将是 pk_agg_201708 在插入之前通常会触发将插入重定向到正确的分区。
问题是我想在这个表中做一个 UPSERT。DO CONFLICT 部分不起作用。
最初的代码是这样的
INSERT INTO aggregated_master (user, type, date, oeprations, amount)
SELECT user, type, date, SUM(ops), SUM(amt)
FROM ...
WHERE ...
GROUP BY USER, TYPE, DATE
ON CONFLICT ON CONSTRAINT pk_aggregated
DO UPDATE SET operations = EXCLUDED.operations
, amount = EXCLUDED.amount
Run Code Online (Sandbox Code Playgroud)
但是后来我注意到约束 …
我有一个如下所示的批量插入功能set_interactions(arg_rows text):
with inserts as (
insert into interaction (
thing_id,
associate_id, created_time)
select t->>'thing_id', t->>'associate_id', now() from
json_array_elements(arg_rows::json) t
ON CONFLICT (thing_id, associate_id) DO NOTHING
RETURNING thing_id, associate_id
) select into insert_count count(*) from inserts;
-- Followed by an insert in an unrelated table that has two triggers, neither of which touch any of the tables here (also not by any of their triggers, etc.)
Run Code Online (Sandbox Code Playgroud)
(我这样包装它是因为我需要计算实际插入的数量,而没有“假行更新”技巧。)
该表interaction有:
触发器执行以下操作:
DECLARE …Run Code Online (Sandbox Code Playgroud) 我遇到了一个死锁场景,死锁的唯一参与者似乎是一个表和一个从该表中删除的存储过程。我根据对其中几个死锁时的 sql 错误日志的分析得出了这个结论,并使用下面的 MSDN 文章作为破译错误日志中的跟踪的指南。
下面定义了表 DEXTable 和存储过程 ClearDEXTableRows。还有另一个存储过程 InsertDEXTableRow 将行插入 DEXTable,但是根据 sql 错误日志中的条目,该过程似乎没有涉及死锁。
DEXTable 中有大约 830 万行,并且趋于稳定增长。受访者表也很大,并且趋于稳定增长。
它是从具有频繁快速连续调用 ClearDEXTableRows 和 InsertDEXTableRow 的页面的高流量网站访问的。
在过去的 10 天内,每天发生 0 到 9 次死锁。
我已经为 1222(使用 DBCC TRACEON 1222)启用了 sql 跟踪,并且最近启用了标志 1204。在检测和结束死锁上有对这些标志的输出的很好的描述
只有这个存储过程 ClearDEXTableRows 是导致死锁的原因是否有意义?
如果是这样,任何人都可以很好地解释这种情况是如何发生的并推荐一种解决方法吗?
我怀疑 DELETE 语句导致 DEXTable 的 PK 争用需要经常重建。
如果没有,我应该启用哪些额外的跟踪来深入挖掘死锁的原因?(我想在这里学习)
-- Table definition
CREATE TABLE [dbo].[DEXTable](
[ExportID] [int] NOT NULL,
[RespondentID] [int] NOT NULL,
[Exported] [datetime] NOT NULL,
CONSTRAINT [PK_DEXTable] PRIMARY KEY CLUSTERED …Run Code Online (Sandbox Code Playgroud) 我在 PostgreSQL 13 中有下表:
field type
----- ----
Seq bigserial
code varchar
Run Code Online (Sandbox Code Playgroud)
Seq是主键(自增)
Code是唯一键索引
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing --> Seq value is 1
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('002') On Conflict(Code) Do Nothing --> Seq value is 4
Run Code Online (Sandbox Code Playgroud)
为什么是序列4?有什么方法可以仅在成功插入时增加价值?
我在 PostgreSQL 9.1 中有一个名为fun_test. 它有一个复合类型作为输入参数,我在调用它时不断收到转换错误。
CREATE OR REPLACE FUNCTION netcen.fun_test(myobj netcen.testobj)
RETURNS boolean AS
$BODY$
DECLARE
tmp_code smallint;
cur_member refcursor;
BEGIN
-- Check if the member exists first
OPEN cur_member FOR
EXECUTE 'SELECT testkey FROM netcen.test WHERE testkey=' || myobj.testkey ;
FETCH cur_member INTO tmp_code;
CLOSE cur_member;
CASE tmp_code
WHEN COALESCE(tmp_code,0)=0 THEN
-- Record not found INSERT a new record
-- will skip user defined validation for now
insert into netcen.test values(myobj.testkey,
myobj.tes,
myobj.testname);
ELSE
-- Record found …Run Code Online (Sandbox Code Playgroud) TL; DR:
插入大量的行的无冲突快得多比(不)重新插入相同的行,BOTH使用INSERT IGNORE语法。
为什么是这样?我假设插入和“忽略”插入的索引查找成本相同,因为 MySQL 不知道传入的数据是否具有重复/冲突的数据(因此需要被忽略)......因此,索引发生在初始插入和被忽略的插入运行中。
此外,我认为“忽略”行应该是便宜的,因为它不需要任何磁盘写入。
但这绝对不是这种情况。
长版:
在这个问题中,我们使用 AWS 的 Aurora/MySQL 和LOAD DATA FROM S3 FILE语法来删除任何传输或性能变量。我们加载了一个与下面架构相对应的 4 兆行 CSV 文件,并加载了两次,每次都使用LOAD ... IGNORE.
请注意,该问题也发生在标准INSERT ... IGNORE,但使用批量行插入时。LOAD ... IGNORE这里的用途是将讨论引向测量结果的反直觉性质,而不是“如何执行大量被忽略的插入”。这不是这里的问题,因为已经制定了特定于域的方法。
在被测试的模型中,有一个三层索引:前两个是基数非常低的可枚举分类列,第三个列本质上是“实际”数据。为了简化这个问题,我只是坚持我目前的设置。
假设以下简单模式:
our_table:
id: basic auto-increment bigint, primary key
constkey1: varchar(50) -- this is a constant in the insert
constkey2: varchar(50) -- this is a constant in the insert
datakey: varchar(50) -- this is pulled in …Run Code Online (Sandbox Code Playgroud) 我想做这个
INSERT INTO AdminAccounts (Name)
SELECT Name
FROM Matrix
Run Code Online (Sandbox Code Playgroud)
但我不想创建重复项。即,我几周前运行了它并且需要更新数据。
在将大量数据推送到 mongo 的大型程序几分钟后,我的日志开始显示(我猜)每次更新的消息。这看起来非常嘈杂,是否有什么特殊原因需要这样做?
Tue Jun 5 14:32:37 [conn3] update benchmark.entity
query: { corefEntityId: "45-LOCATION" }
update: { $set: { corefEntityId: "45-LOCATION", type: "Location" },
$push: { indocs: { docid: "cfcc403b-714f-4c5d-8507-ccb5b6354654",
ordinal: 26, label: "United States", mentions: [ "United States" ] } },
$addToSet: { allMentions: { $each: [ "United States" ] } },
$inc: { documentCount: 1 } } 116ms
Run Code Online (Sandbox Code Playgroud)
作为一个可能更容易回答的脚注,我想知道:与将普通插入到内部文档的其他集合中作为顶级文档相比,添加到某些内部文档的“upsert”是否更快或更慢?
upsert ×10
postgresql ×6
plpgsql ×3
deadlock ×2
mysql ×2
aurora ×1
bulk-insert ×1
concurrency ×1
cte ×1
index ×1
insert ×1
logs ×1
mongodb ×1
primary-key ×1
sequence ×1