2017-01-27 1 views
2

Dans mon tableau plin_korisnik, j'ai le champ actif qui est défini comme type booléen.Postgres SQL - problème de performance avec champ booléen

Je suis en train d'exécuter cette requête pour extraire des données de cette table et deux autres tables:

SELECT 
    pk.omm AS omm, 
    pk.br_plin AS br_plin, 
    pk.naziv AS naziv, 
    pk.ulica||' '||pk.kbr AS adresa, 
    pk.pu||' - '||pk.naziv_pu AS mjesto, 
    po.datum AS datum, 
    CASE WHEN po.stanje >= 999999 THEN NULL ELSE po.stanje END AS stanje, 
    po.napomena AS napomena, 
    po.plin_postar AS laus, 
    pp.ime||' '||pp.prezime AS postar 
FROM plin_korisnik pk 
INNER JOIN 
    plin_ocitanje po ON pk.omm = po.omm 
INNER JOIN plin_postar pp ON pp.laus = po.plin_postar 
WHERE po.datum>='2017-01-26' 
    AND po.datum<='2017-01-26' 
    AND pk.tip='p' 
    AND pk.active = TRUE 
ORDER BY po.datum, pk.naziv 

mais requête prend beaucoup de temps à (comme toujours, j'interrompu après une demi-heure), mais lorsque je supprime le test pk.active = TRUE de la clause WHERE, la requête s'exécute avec la vitesse attendue. J'ai essayé de convertir le type booléen en entier, mais le problème persiste.

Je vous serais reconnaissant si quelqu'un pourrait expliquer comment utiliser un champ booléen dans cette requête et similaires. actif Le champ n'est pas indexé, peut-être que cela devrait l'être, s'il vous plaît, aidez-nous.

EDIT: Après quelques heures de réflexion, je suis sorti avec cette solution utilisant la clause WITH:

WITH pk AS (
    SELECT * FROM plin_korisnik WHERE active AND tip='p' 
) 
SELECT 
    pk.omm AS omm, 
    pk.br_plin AS br_plin, 
    pk.naziv AS naziv, 
    pk.ulica||' '||pk.kbr AS adresa, 
    pk.pu||' - '||pk.naziv_pu AS mjesto, 
    po.datum AS datum, 
    CASE WHEN po.stanje >= 999999 THEN NULL ELSE po.stanje END AS stanje, 
    po.napomena AS napomena, 
    po.plin_postar AS laus, 
    pp.ime||' '||pp.prezime AS postar 
FROM pk 
INNER JOIN 
    plin_ocitanje po ON pk.omm = po.omm 
INNER JOIN plin_postar pp ON pp.laus = po.plin_postar 
WHERE po.datum>='2017-01-26' 
    AND po.datum<='2017-01-26' 
ORDER BY po.datum, pk.naziv; 
+0

Pourquoi ne pas ajouter un index 'active'? –

+4

Please ** [EDIT] ** votre question et ajoutez le plan d'exécution généré en utilisant ** 'explain (analyser, verbose)' ** pour la requête rapide et un simple 'explain' pour la requête que vous avez annulée. [** Texte formaté **] (http://stackoverflow.com/help/formatting) s'il vous plaît, [aucune capture d'écran] (http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload-images-de-code-sur-alors-quand-pose-une-question/285557 # 285557) –

+0

Que vous @TimBiegeleisen. J'ai créé l'index sur la colonne "active", et la requête se termine maintenant après 13sec, ce qui est acceptable. La plupart des références sur Internet disent qu'il ne sert à rien de faire index sur une colonne booléenne. La table n'est pas si grande 250.000+ rangées dont 12.000+ lignes sont "actives". –

Répondre

1

Je pense que vous pouvez le rendre plus rapide si vous modifiez l'ordre dans la clause where, commencez par le table initiale. Un index sur pk.active et sur po.datum sera absolument utile. Vous pouvez envisager de placer le fichier po.datum dans la jointure interne, au lieu de l'endroit où.

po.datum>='2017-01-26' 
AND po.datum<='2017-01-26' 
AND pk.tip='p' 
AND pk.active = TRUE 

Sera:

pk.active = TRUE 
AND pk.tip='p' 
AND po.datum>='2017-01-26' 
AND po.datum<='2017-01-26' 
+0

Comment la commande ferait-elle une différence? –

+0

L'ordre dans lequel peut/devrait affecter l'ordre d'exécution de la requête. Si la base de données peut ignorer 238000 des 250000 lignes (voir le commentaire ci-dessus) après la première où elle sera plus rapide. vérifier un booléen dans la table de gauche est plus rapide que de vérifier 2 champs de date dans le tableau de droite – verhie

+0

@Bojan s'il vous plaît essayez ceci et dites-nous ce qui s'est passé –