【问题标题】:How to Never Retrieve Different Rows in a Changing Table如何从不检索变化表中的不同行
【发布时间】:2017-03-14 21:18:14
【问题描述】:

我有一个包含数百万行的表,该表不断变化(插入、更新新行,还有一些被删除)。我想每分钟查询 100 个新行(我以前没有查询过),但这些行不能是我以前查询过的行。该表有大约 2 打列和一个主键。

很乐意回答任何问题或提供说明。

【问题讨论】:

  • “新行”是指新插入还是更新?
  • @Gab 两者,新的插入和旧的行不断更新。
  • 是的,但是“我想查询 100 条新行”,是只插入还是最近更新的行?
  • @Gab 只是我以前没有查询过的行,我不在乎它们是最近更新还是最近插入的。我只关心我之前是否询问过他们。
  • 我写了一个架构并回答了你的问题。

标签: sql postgresql limit offset


【解决方案1】:

一个简单的解决方案是有一个单独的表,其中只有一行来存储您获取的最后一个 ID。

假设这是您的“数百万行表”:

-- That's your table with million of rows
CREATE TABLE test_table (
    id serial unique,
    col1 text,
    col2 timestamp
);

-- Data sample
INSERT INTO test_table (col1, col2)
SELECT 'test', generate_series
FROM generate_series(now() - interval '1 year', now(), '1 day');

您可以创建下表来存储 ID:

-- Table to keep last id
CREATE TABLE last_query (
  last_quey_id int references test_table (id)
);
-- Initial row
INSERT INTO last_query (last_quey_id) VALUES (1);

然后使用以下查询,您将始终获取 100 行从未从原始表中获取的行,并在 last_query 中维护一个指针:

WITH last_id as (
    SELECT last_quey_id FROM last_query
), new_rows as (
    SELECT *
    FROM test_table
    WHERE id > (SELECT last_quey_id FROM last_id)
    ORDER BY id
    LIMIT 100
), update_last_id as (
    UPDATE last_query SET last_quey_id = (SELECT MAX(id) FROM new_rows)
)
SELECT * FROM new_rows;

将按新 ID 的顺序获取行(最旧的行在前)。

【讨论】:

    【解决方案2】:

    您基本上需要为该表中的每条记录分配一个唯一的、连续的值。这使您可以搜索该字段的值大于您从上一页获得的最后一条记录的下 X 条记录。

    最简单的方法是将标识列作为您的 PK,然后从头开始并在查询中包含“where id > @last_id”过滤器。这是一种相当简单的数据分页方式,无论底层更新如何。但是,如果您已经有数百万行并且不断地创建和更新,那么一个普通的整数标识最终会用完数字(一个 bigint 标识列在您的曾孙辈的一生中不太可能用完数字,但不会所有数据库都支持除 32 位身份之外的任何内容)。

    您可以对“CreatedDate”日期时间列执行相同的操作,但由于这些日期不能 100% 保证是唯一的,具体取决于此日期的设置方式,您可能有多个具有相同创建时间戳的行,如果这些记录跨越“页面边界”,您将错过任何超出当前页面末尾的记录。

    保证某些 SQL 系统的 GUID 生成器不仅是唯一的,而且是连续的。您必须研究 PostgreSQL 的 GUID 是否以这种方式工作;如果它们是真正的 V4 GUID,它们将是完全随机的,除了版本标识符并且您是 SOL。如果您确实有权访问顺序 GUID,则可以像使用整数标识列一样进行过滤,仅使用更多可能的键值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 2015-10-06
      • 1970-01-01
      相关资源
      最近更新 更多