estimated vs actual in analyze

hallo,

in meinem queryplan gibts riesige unterschiede zwischen estimated und actual values
hier der volle plan:
explain-analyze.info | afdsafs
in der ersten zeile sieht man was ich meine:

Nested Loop (cost=225539.96..778456.22 rows=3 width=58) (actual time=116920.345..258346.070 rows=31362 loops=1)

dabei habe ich vacuum und analyze über alle tabellen laufen lassen und es sind keine updates oder ähnliches passiert.

kann es sein, dass aufgrund der subqueries in meinem select der planer nicht zurecht kommt und falsche vorhersagen berechnet?

hier die query falls es interessiert. sie funktioniert ohne probleme,bisschen langsam aufgrund der subselects, mich verwundert nur der queryplan (ja ich weiß die subqueries bremsen und man könnte es sicher schöner lösen, aber mein ORM (hibernate) zwingt mich förmlich dazu :frowning: )

explain analyze 
SELECT person0_.FIRSTNAME AS col_0_0_,
       person0_.LASTNAME AS col_1_0_,
       person0_.EMAIL_ADDRESS AS col_2_0_,
       person0_.MOBILE_NUMBER AS col_3_0_
FROM dwh_test.PERSON person0_,
     dwh_test.STATS stats1_
WHERE (person0_.EMAIL_ADDRESS IN (SELECT DISTINCT person3_.EMAIL_ADDRESS
                                  FROM dwh_test.STATS stats2_,
                                       dwh_test.PERSON person3_,
                                       dwh_test.PERMISSION_EMAIL permission4_ 
                                       INNER JOIN dwh_test.PERMISSION permission4_1_ ON permission4_.id = permission4_1_.id,
                                       dwh_test.GEO_DATA geodata5_
                                  WHERE stats2_.ENABLED_STATUS = 1
                                  AND   permission4_1_.PERMISSION_FLAG = 1
                                  AND   geodata5_.COUNTRY = 'at'
                                  AND   (geodata5_.ZIP_CODE IN ('1010','1020','1030','1040','1050','1060','1070','1080','1090','1100','1110','1120','1130','1140','1150','1160','1170','1180','1190','1200','1210','1220','1230','1300','2201','2202','2281','2325','2332','2333','2351','2372','2384','2392','2393','2432','2500','2532','2641','2700','3223'))
                                  AND   geodata5_.PERSON = person3_.id
                                  AND   permission4_.PERSON = person3_.id
                                  AND   stats2_.PERSON = person3_.id))
AND   stats1_.PERSON = person0_.id
AND   stats1_.LAST_LOGIN = (SELECT MAX(stats6_.LAST_LOGIN)
                            FROM dwh_test.STATS stats6_,
                                 dwh_test.PERSON person7_
                            WHERE stats6_.PERSON = person7_.id
                            AND   person7_.EMAIL_ADDRESS = person0_.EMAIL_ADDRESS);

kurze erklärung:

  • ich selektiere alle distinct emailadressen der user die meinen kriterien entsprechen (1tes subselekt mit zip_codes, enabled, usw…)
  • nun selektiere ich alle felder die mich zu den emailadressen interessieren (name, geburtsdatum, o.ä.)
  • da eine emailadresse öfters vorkommen kann, muss ich mich pro doppelter emailadressen für einen user entscheiden
  • der gewählte user ist der, der sich als letzter angemeldet hat (2tes subselect mit max(last_login)

Hab grad nicht viel Zeit, daher nur kurz drüber geschaut. Du könntest versuchen, via alter table … ALTER [ COLUMN ] spalte SET STATISTICS integer die Statistiken zu verbessern. Wirkt manchmal Wunder.

Kann aber sein, daß das hier nicht viel hilft, wegens der subqueries.

Andreas

ok schonmal danke. gibts da irgendwelche faustregeln? hab gelesen der wert liegt zwischen 1 und 1000 aber jetzt per trial und error hier einfach werte zu setzen… weiß nicht ob da was gescheites raus kommt…

Naja, wenn man sich das anschaut, sieht man, daß bis zu diesem Schritt ja schon eine Menge Zeit rum ist. Mit anderen Worten: dieser Schritt hat nicht so dolle Einfluß insgesamt auf die Laufzeit. Weiß nicht, ob man da was optimieren kann, im inneren sind ja eh alles Index-Scans.

Vielleicht wissen Leute auf der [Performance]-ML mehr als ich.

Andreas

ok nicht so schlimm. hätte mich nur interessiert woran das liegen kann. vlt schreib ich auch mal das ganze händisch um und versuch die subselects durch joins zu ersetzen oder die anonymen subselects in die from-clause zu setzen. leider würde mir das dann nichts nützen, da die obige query nicht mehr groß verändert werden kann. hibernate unterstützt nur subselects in select oder where klauseln…

[Performance]-ML ?? :slight_smile:

//edit: ok jetzt klingelts… mailinglist kopf → tisch werd da mal nachfragen. thx!

[PERFORM]-Mailinglist:

List-Archive: <http://archives.postgresql.org/pgsql-performance>
List-Help: <mailto:majordomo@postgresql.org?body=help>
List-ID: <pgsql-performance.postgresql.org>
List-Owner: <mailto :p gsql-performance-owner@postgresql.org>
List-Post: <mailto :p gsql-performance@postgresql.org>
List-Subscribe: <mailto:majordomo@postgresql.org?body=sub%20pgsql-performance>

Andreas