2017-03-14 9 views
1

私は常に変化する数百万行のテーブルを持っています(新しい行が挿入され、更新され、一部が削除されます)。私は毎分100回の新しい行を照会したいと思いますが、これらの行は前に照会した行にはなりません。テーブルには約2ダースの列と主キーがあります。変更テーブル内の異なる行を検索しない方法

ご不明な点がございましたら、お気軽にお問い合わせください。

+0

「新しい行」とは、新しい挿入物または更新プログラムを意味しますか? – Gab

+0

@Gab両方とも、新しい挿入が行われ、古い行が絶えず更新されます。 –

+0

はい、「100個の新しい行を照会したいですか」というのは、その挿入だけか、最近更新された行ですか? – Gab

答えて

1

基本的に、このテーブルの各レコードに割り当てられた一意の順次値が必要です。これにより、このフィールドの値が前のページから最後に取得したものよりも大きい次のXレコードを検索することができます。

最も簡単な方法は、あなたのPKとしてID列を持ち、単に最初から始め、クエリに "where id> @last_id"フィルタを含めることです。これは、基礎となる更新に関係なく、データをページングするかなり簡単な方法です。しかし、すでに何百万行もあり、常に作成して更新している場合、通常の整数のIDには最終的に数字がなくなります(bigintのID列は孫の寿命ではなくなりそうですが、すべてのDBは32ビットID以外のものをサポートしています)。

"CreatedDate" datetime列でも同じことができますが、これらの日付は100%保証されていないため、この日付の設定方法によっては同じ作成で複数の行がある可能性がありますこれらのレコードが「ページ境界」を超えている場合は、現在のページの終わりを超えて発生することはありません。

一部のSQLシステムのGUIDジェネレータは、一意ではなくシーケンシャルであることが保証されています。 PostgreSQLのGUIDがこのように動作するかどうかを調べなければなりません。彼らが真のV4 GUIDであれば、バージョン識別子を除いて完全にランダムになり、あなたはSOLになります。シーケンシャルGUIDにアクセスできる場合は、整数アイデンティティ列と同様に、より多くのキー値でフィルタリングできます。

2

単純な解決策は、取り出した最後のIDを格納するために1行だけの別のテーブルを用意することです。

のは、それはあなたの「数百万行のテーブル」だとしましょう:

-- 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の順番で行がフェッチされます(最も古い行が最初に表示されます)。

関連する問題