Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PostgreSQL索引中包含两次列_Sql_Postgresql - Fatal编程技术网

在PostgreSQL索引中包含两次列

在PostgreSQL索引中包含两次列,sql,postgresql,Sql,Postgresql,我正在构建一个基于PostgreSQL的工作队列,如上所述 我的队列定义与本文中描述的概念略有不同,它使用目标时间戳进行消费(due\u time): 只有一个索引: CREATE INDEX idx_publish_due_created ON publish_queue( due_time ASC NULLS FIRST, created ASC) WHERE(NOT is_complete); 让我们用测试数据集填充该表: begin transaction; INSERT INTO p

我正在构建一个基于PostgreSQL的工作队列,如上所述

我的队列定义与本文中描述的概念略有不同,它使用目标时间戳进行消费(
due\u time
):

只有一个索引:

CREATE INDEX idx_publish_due_created ON publish_queue(
due_time ASC NULLS FIRST, created ASC) WHERE(NOT is_complete);
让我们用测试数据集填充该表:

begin transaction;
INSERT INTO publish_queue(article_id, due_time)
SELECT 2407, t.day::date FROM generate_series(timestamp '2024-03-07', timestamp '2034-08-16',interval  '1 minute') AS t(day);
commit;
并消费一件物品:

update publish_queue
set is_complete = true, completed = now()
where id = (
  select id
  from publish_queue
  WHERE NOT is_complete AND (LOCALTIMESTAMP >= due_time OR due_time IS NULL)
  order by due_time ASC NULLS FIRST, created ASC
  for update skip locked
  limit 1
)
returning article_id;
在我的系统上,查询需要约2秒钟才能完成,执行计划如下:

但是,如果我像下面这样更改索引,包括第二次更改到期时间,这是我以前从未做过的

CREATE INDEX idx_publish_due_created ON publish_queue(
due_time, due_time ASC NULLS FIRST, created ASC) WHERE(NOT is_complete);
查询耗时60毫秒,结果如下:


现在我的问题是,在索引中包含两次列感觉很奇怪。我是不是遗漏了什么?使用不同的索引或重新表述查询是否可以实现同样的效果?

是的,这很奇怪。你可以做得更好:

CREATE INDEX ON (coalesce(due_time, '-infinity'::timestamp), created);
然后像这样查询:

SELECT id
FROM publish_queue
WHERE NOT is_complete
  AND LOCALTIMESTAMP >= coalesce(due_time, '-infinity'::timestamp)
ORDER BY coalesce(due_time, '-infinity'::timestamp), created
FOR UPDATE SKIP LOCKED
LIMIT 1

如果只包含一次,而不先为
?@a_horse_,带有_no_名称,这就是它。为了让我接受你的评论,你能把它变成一个答案吗?一个没有名字的马的评论是正确的,但这也是有效的。
SELECT id
FROM publish_queue
WHERE NOT is_complete
  AND LOCALTIMESTAMP >= coalesce(due_time, '-infinity'::timestamp)
ORDER BY coalesce(due_time, '-infinity'::timestamp), created
FOR UPDATE SKIP LOCKED
LIMIT 1