J'ai un tas de lignes que je dois insérer dans le tableau, mais ces insertions sont toujours faites par lots. Je veux donc vérifier si une seule ligne du lot existe dans le tableau car je sais alors qu'ils ont tous été insérés.
Ce n'est donc pas une vérification de clé primaire, mais cela ne devrait pas trop avoir d'importance. Je voudrais ne vérifier qu'une seule ligne, donc ce count(*)
n'est probablement pas bon, donc c'est quelque chose comme exists
je suppose.
Mais comme je suis assez nouveau dans PostgreSQL, je préfère demander aux gens qui savent.
Mon lot contient des lignes avec la structure suivante:
userid | rightid | remaining_count
Donc, si la table contient des lignes fournies, userid
cela signifie qu'elles y sont toutes présentes.
sql
postgresql
Valentin Kuzub
la source
la source
Réponses:
Utilisez le mot clé EXISTS pour un retour TRUE / FALSE:
la source
select exists(select 1 from contact where id=12) AS "exists"
exists
oulimit 1
j'ai une forte baisse de performances parce que Postgres utilise Seq Scan au lieu de Index Scan. Etanalyze
n'aide pas.Que diriez-vous simplement:
où
123
est l'ID utilisateur du lot que vous êtes sur le point d'insérer.La requête ci-dessus renverra un ensemble vide ou une seule ligne, selon qu'il existe des enregistrements avec l'ID utilisateur donné.
Si cela s'avère trop lent, vous pouvez envisager de créer un index sur
tbl.userid
.Pour que cela reste vrai même si votre programme est interrompu au milieu du lot, je vous recommande de vous assurer de gérer correctement les transactions de la base de données (c'est-à-dire que le lot entier est inséré dans une seule transaction).
la source
COUNT
agit sur un imbriquéSELECT
qui a au plus 1 ligne (car leLIMIT
est dans la sous-requête).BTW: si vous voulez que tout le lot échoue en cas de duplication, alors (étant donné une contrainte de clé primaire)
fera exactement ce que vous voulez: soit il réussit, soit il échoue.
la source
Je crois que c'est la requête que postgres utilise pour vérifier les clés étrangères.
Dans votre cas, vous pouvez également le faire en une seule fois:
la source
comme l'a souligné @MikeM.
avec un index sur contact, il peut généralement réduire le coût en temps à 1 ms.
la source
Si votre jeu de résultats contient une ligne, vous n'avez pas besoin d'insérer. Sinon, insérez vos enregistrements.
la source
Si vous pensez à la performance, vous pouvez peut-être utiliser "PERFORM" dans une fonction comme celle-ci:
la source
Je voudrais proposer une autre réflexion pour répondre spécifiquement à votre phrase: "Je veux donc vérifier si une seule ligne du lot existe dans le tableau parce qu'alors je sais qu'elles ont toutes été insérées ."
Vous rendez les choses efficaces en insérant des "lots" mais en effectuant ensuite des vérifications d'existence un enregistrement à la fois? Cela me semble contre-intuitif. Donc, quand vous dites "les insertions sont toujours effectuées par lots ", je suppose que vous voulez dire que vous insérez plusieurs enregistrements avec une instruction d'insertion . Vous devez vous rendre compte que Postgres est conforme à ACID. Si vous insérez plusieurs enregistrements (un lot de données) avec une instruction d'insertion , il n'est pas nécessaire de vérifier si certains ont été insérés ou non. L'instruction réussit ou échouera. Tous les enregistrements seront insérés ou aucun.
D'un autre côté, si votre code C # fait simplement un "set" d'instructions d'insertion séparées, par exemple, dans une boucle, et dans votre esprit, c'est un "batch" .. alors vous ne devriez pas en fait le décrire comme " les insertions se font toujours par lots ". Le fait que vous vous attendiez à ce qu'une partie de ce que vous appelez un "lot" ne soit en fait pas insérée, et par conséquent ressentiez le besoin d'une vérification, suggère fortement que c'est le cas, auquel cas vous avez un problème plus fondamental. Vous devez modifier votre paradigme pour insérer réellement plusieurs enregistrements avec une seule insertion et renoncer à vérifier si les enregistrements individuels l'ont fait.
Prenons cet exemple:
C'est en fait le paradigme de toute base de données compatible ACID ... pas seulement de Postgresql. En d'autres termes, vous êtes mieux si vous corrigez votre concept de «lot» et évitez d'avoir à faire des vérifications ligne par ligne en premier lieu.
la source