2017-03-14 3 views
1

Ich habe eine Tabelle mit Millionen von Zeilen, die sich ständig ändern (neue Zeilen werden eingefügt, aktualisiert und einige werden gelöscht). Ich möchte jede Minute 100 neue Zeilen abfragen (ich habe noch nie abgefragt), aber diese Zeilen können nicht die sein, die ich vorher abgefragt habe. Die Tabelle hat etwa 2 Dutzend Spalten und einen Primärschlüssel.So rufen Sie nie unterschiedliche Zeilen in einer Tabelle ab

Gerne, um Fragen zu beantworten oder zu klären.

+0

Mit "neuen Zeilen" meinen Sie neue Einsätze oder auch Updates? – Gab

+0

@Gab Beide, neue Inserts werden gemacht und alte Zeilen werden ständig aktualisiert. –

+0

Ja, aber "Ich möchte 100 neue Zeilen abfragen", sind das nur die Inserts oder auch die Zeilen, die kürzlich aktualisiert wurden? – Gab

Antwort

1

Sie benötigen grundsätzlich einen eindeutigen, sequenziellen Wert, der zu jedem Datensatz in dieser Tabelle zugeordnet ist. Dadurch können Sie nach den nächsten X-Datensätzen suchen, bei denen der Wert dieses Felds größer ist als der letzte Wert auf der vorherigen Seite.

Der einfachste Weg wäre eine Identitätsspalte als PK zu haben, und einfach von Anfang an beginnen und beinhalten eine „where id> @last_id“ Filter auf Ihre Anfrage. Dies ist eine relativ einfache Methode zum Durchblättern von Daten, unabhängig von den zugrunde liegenden Aktualisierungen. Wenn Sie jedoch bereits über Millionen von Zeilen verfügen und ständig neue erstellen und aktualisieren, wird eine gewöhnliche Integer-Identität irgendwann keine Zahlen mehr haben (eine Bigint-Identitätsspalte wird wahrscheinlich nicht die Lebenszeit Ihrer Urenkel umfassen, aber nicht Alle DBs unterstützen alles außer einer 32-Bit-Identität).

Sie können das gleiche mit einer DateTime-Spalte "CreatedDate" tun, aber da diese Daten nicht zu 100% eindeutig sind, je nachdem, wie dieses Datum eingestellt ist, können Sie mehr als eine Zeile mit derselben Erstellung haben Zeitstempel, und wenn diese Datensätze eine "Seitengrenze" überschreiten, werden Sie alle über das Ende Ihrer aktuellen Seite hinaus auftreten.

Some GUID Generatoren SQL-System garantiert nicht nur einzigartig, sondern sequentiell sein. Sie müssen prüfen, ob die GUIDs von PostgreSQL auf diese Weise funktionieren. Wenn es sich um echte V4-GUIDs handelt, sind sie bis auf die Versionskennung völlig zufällig und Sie sind SOL. Wenn Sie Zugriff auf sequentielle GUIDs haben, können Sie genau wie bei einer Integer-Identitätsspalte nur mit viel mehr möglichen Schlüsselwerten filtern.

2

Eine einfache Lösung ist mit nur einer Zeile eine separate Tabelle zu haben, die letzte ID speichern Sie geholt.

Lassen Sie uns sagen, das ist Ihre „Tisch von Millionen von Zeilen“:

-- 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'); 

Sie können die folgende Tabelle erstellen eine ID zu speichern:

-- 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); 

Dann mit der folgenden Abfrage, werden Sie immer Holen Sie 100 Zeilen, die nie aus der Originaltabelle abgerufen wurden, und führen Sie einen Zeiger in 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; 

Zeilen werden nach der Reihenfolge der neuen IDs abgerufen (zuerst die ältesten Zeilen).

Verwandte Themen