2017-02-23 3 views
1

Je ne parviens pas à comprendre cela. La requête ci-dessus compte les enregistrements en double des profils (pour lesquels les artefacts ont plusieurs enregistrements). Quand je lance la requête ci-dessus avec distinct, j'obtiens le compte correct qui est ci-dessous.Pourquoi une requête dans les résultats de la requête dans des enregistrements en double

SELECT COUNT(DISTINCT(id)) FROM profiles 
WHERE profiles.status IN ('abc', 'man') 
    AND profiles.id IN (
         SELECT artifacts.item_id FROM artifacts 
         WHERE artifacts.deleted_at IS NULL 
          AND artifacts.item_type = 'Profile' 
          AND artifacts.upload_type = 'bill' 
        ); 
count 
------- 
12157 
(1 row) 

Les artefacts peuvent avoir plusieurs enregistrements pour le même profil. Mais selon ma compréhension IN requête ne laissera aucun profil en double à venir en compte. Ai-je raison? ou y a-t-il quelque chose qui me manque?

MISE À JOUR:

j'ai essayé de réduire la requête 2 conditions de filtrage différentes. Les deux conditions fonctionnent bien. Veuillez trouver ci-dessous.

=> SELECT COUNT(*) FROM profiles WHERE profiles.id IN (
      SELECT artifacts.item_id FROM artifacts 
      WHERE artifacts.deleted_at IS NULL 
      AND artifacts.item_type = 'Profile' 
      AND artifacts.upload_type = 'bill'); 
count 
------- 
22664 
(1 row) 

=> SELECT COUNT(DISTINCT(id)) FROM profiles WHERE profiles.id IN (
      SELECT artifacts.item_id FROM artifacts 
      WHERE artifacts.deleted_at IS NULL 
      AND artifacts.item_type = 'Profile' 
      AND artifacts.upload_type = 'bill'); 
count 
------- 
22664 
(1 row) 


=> SELECT COUNT(DISTINCT(id)) FROM profiles 
     WHERE profiles.status IN ('abc', 'man'); 
count 
------- 
20109 
(1 row) 

=> SELECT COUNT(*) FROM profiles 
     WHERE profiles.status IN ('abc', 'man'); 
count 
------- 
20109 

Donc, la duplication se produit lorsque deux IN requêtes utilisées dans conjuction. Quelqu'un connaît-il ce cas d'utilisation?

+1

Voici une question stupide - avez-vous des doublons dans la table des profils? – paqash

+0

@paqash Pas possible. Id est la clé primaire. – dnsh

+0

essayez d'exécuter 'SELECT id FROM profils ... sauf SELECT distinct id FROM profiles..' pour obtenir la liste de" not distinct id "? .. –

Répondre

0

Il y a deux possibilités:

  1. id est pas unique dans profiles.

    Vous pouvez exécuter la requête suivante pour enquêter sur ceci:

    SELECT profiles.id, count(*) FROM profiles 
    WHERE profiles.status IN ('abc', 'man') 
        AND profiles.id IN (
             SELECT artifacts.item_id FROM artifacts 
             WHERE artifacts.deleted_at IS NULL 
              AND artifacts.item_type = 'Profile' 
              AND artifacts.upload_type = 'bill' 
            ) 
    GROUP BY profiles.id 
    HAVING count(*) > 1; 
    

    qui renverra les id s qui sont en double.

    Vous ne disposez pas d'une contrainte UNIQUE ou PRIMARY KEY sur cette colonne? S'il existe une contrainte UNIQUE ou PRIMARY KEY sur id, vous êtes confronté à une corruption de données. Regardez le plan de requête – utilise-t-il des analyses d'index ou des analyses séquentielles?

    Si le réglage enable_indexscan, enable_bitmapscan et enable_indexonlyscan à off résout le problème, vous avez un index corrompu. REINDEX TABLE profiles va probablement résoudre le problème.

    Si la requête renvoie également de mauvais résultats si seules les analyses séquentielles sont utilisées, vous êtes confronté à une corruption de table. Restaurer à partir de la dernière bonne sauvegarde.

    Dans tous les cas, s'il s'agissait d'une corruption de données, trouvez sa cause et corrigez-la. Il peut s'agir d'une RAM ou d'un stockage défectueux ou d'un blocage du stockage sur un serveur qui n'honore pas correctement les requêtes de synchronisation. Lisez les journaux de la base de données!