2013-06-14 2 views
2

Ma question originale avec tout le contexte pertinent peut être trouvé ici:
Adding a multi-column primary key to a table with 40 million recordsVérifiez les lignes en double complètes dans une grande table

J'ai une table avec 40 millions de lignes et pas de clé primaire. Avant d'ajouter la clé primaire, je voudrais vérifier si la table a des entrées en double. Quand je dis des entrées en double, je ne veux pas simplement dire dupliquer sur des colonnes particulières. Je veux dire des doublons sur des lignes entières.

On m'a dit dans ma dernière question que je peux faire une requête EXISTS pour déterminer les doublons. Comment ferais-je cela?

Je cours PostgreSQL 8.1.22. (Vous avez cette information en exécutant select version()).

Répondre

1

pour savoir si une double complète existe (identique sur toutes les colonnes), ce qui est probablement le moyen le plus rapide:

SELECT EXISTS (
    SELECT 1 
    FROM tbl t 
    NATURAL JOIN tbl t1 
    WHERE t.ctid <> t1.ctid 
    ) 

NATURAL JOIN est un raccourci très pratique pour le cas parce que (citant the manual here) :

NATURAL is shorthand for a USING list that mentions all columns in the two tables that have the same names.

EXISTS est probablement le plus rapide, parce que la recherche arrête Postgres dès la fi Le premier duplicata est trouvé. Puisque vous n'avez probablement pas un index couvrant toute la ligne et votre table est énorme, cela vous permettra d'économiser beaucoup de temps.

Soyez conscient que NULL est jamais considéré identique à un autre NULL. Si vous avez des valeurs NULL et les considérez comme identiques, vous devrez en faire plus.

ctid is a system column qui peut être (ab-) utilisé comme clé primaire ad-hoc, mais ne peut remplacer à long terme une clé primaire définie par l'utilisateur.


La version obsolète 8.1 semble avoir aucun opérateur <> défini pour un ctid. Essayez coulée à text:

SELECT EXISTS (
    SELECT 1 
    FROM tbl t 
    NATURAL JOIN tbl t1 
    WHERE t.ctid::text <> t1.ctid::text 
    ) 
+0

Je reçois une erreur: ERREUR: l'opérateur n'existe pas: tid <> tid TRUC: Aucun opérateur correspond au type nom et argument donné (s). Vous devrez peut-être ajouter des conversions de types explicites. – shaun

+1

@ user1338584: Un autre problème avec la version obsolète. Encore une fois: vous avez vraiment besoin d'une mise à niveau .. J'ai ajouté une solution de contournement. –

0

ne devrait pas quelque chose comme ça faire le travail? Je ne sais pas si c'est le moyen le plus efficace, mais compte> 1 signifie que vous avez deux lignes identiques.

Questions connexes