Optimieren

Hallo,
ich habe folgende SQL Abfrage durchzuführen, sie ist aber zu langsam :

select id,name,vorname,adresse from address where id=5

Ich habe schon ein Index auf den Feld id erstellt, aber postgresql benutzt es nicht.

Die Tabelle address hat etwa 30 Felder und 7000 Einträge.

Kann ich denn über PHP irgendwie zwingen, das Index zu benutzen ?

moin,

versuch das ganze nochmal nach einem

REINDEX address;

das hab ich schon mal gehabt, das er den index nicht sauber aufgebaut hat…

cu tb.

Hi Xandrian,
ich habe das schon ausprobiert, aber es hat sich nicht geändert, ich habe schon vacuum, analyze, und reindex gemacht. :frowning:

Erste Frage, welcher Spaltentyp ist ‘id’?
Zweite Sache: führe einmal VACUUM ANALYZE aus.
Dritte Sache, setz das Value mal in Hochkommas, also:

WHERE id = '5'

Was sagt der Explain dann?

Hallo mzda,

mal nachgefragt!

langsam ?
Welche Zeit ist denn bei Dir langsam? Wo hast Du sie gemessen. Direkt am Server oder übers Netz?

30 Felder ?
Die Anzahl der Felder ist uninteressant! Die Länge eines Datensatzen spielt eine Rolle (Blockgröße).

index id?
Ist das ein PK?

Wie sieht es mit deiner Hardware aus, die spielt auch eine große Rolle.

Das Du den Befehl mit EXPLAIN untersucht hast, setze ich mal vorraus. Den Inhalt des Kapitels “11.9. Examining Index Usage” sollte Dir auch bekannt sein. Und die Performance Tips aus Kapitel 13 hast Du auch schon alle befolgt!



Vielleicht helfen Dir dann dieses Links weiter:

http://www.powerpostgresql.com/PerfList
http://www.varlena.com/varlena/GeneralBits/Tidbits/perf.html

Und auf der Seite http://www.powerpostgresql.com/Docs/ kanst Du auch noch weitere nützliche Information finden.



mfg

fristo

Hallo,
danke für die Feedbacks.

Jetzt weiss ich, warum pg das Index nicht genommen hat, nämlich wegen den Hochkommas :smiley: Danke ads.

Ich habe aber eine andere Abfrage, die “langsam” läuft.

select kk_view.*,format_url(kk_view.kk1) as kk1link,format_url(kk_view.kk2) as kk2link from kk_view join firma_kernkompetenzen on kk_view.kk2id = firma_kernkompetenzen.kernkompetenzen_id where firma_kernkompetenzen.firma_id='5' and kernkompetenzen_in_anwendung(kk_view.kk2id,'45')

und das Analyze dazu :

Nested Loop  (cost=0.00..44.04 rows=3 width=52)
  ->  Nested Loop  (cost=0.00..34.86 rows=2 width=34)
        ->  Index Scan using fki_firma_kernkompetenzen_firma_id on firma_kernkompetenzen  (cost=0.00..16.52 rows=4 width=8)
              Index Cond: (firma_id = 5::bigint)
        ->  Index Scan using kernkompetenzen_pkey on kernkompetenzen kk2  (cost=0.00..4.57 rows=1 width=34)
              Index Cond: (kk2.id = "outer".kernkompetenzen_id)
              Filter: kernkompetenzen_in_anwendung(id, 45::bigint)
  ->  Index Scan using kernkompetenzen_pkey on kernkompetenzen kk1  (cost=0.00..4.57 rows=1 width=26)
        Index Cond: (kk1.id = "outer".par_id)

Diese Abfrage dauert etwa 50 ms. Und es ist mir nicht klar, warum es langsam ist. Ist es halt so, oder weil die Abfrage nicht optimiert ist ?

Das ist nicht wegen der Hochkommas, die sind nur ein guter Umweg, das Problem zu umgehen. Eigentlich ist folgendes passiert:

Du vergleichst zwei Spalten mit unterschiedlichen Datentypen. In deinem Fall ist ‘id’ wohl ein BIGSERIAL, also ein BIGINT vom Typ her. Wenn du jetzt in deiner Abfrage nach “id = 5” suchst, ohne für den Wert 5 einen Datentyp anzugeben, nimmt PostgreSQL automatisch Integer an.
Beim Scannen der Tabelle muss PG nun für jeden Eintrag erst mal den Integer 5 nach Bigint casten, um dann zu vergleichen.
Gibst du PG jedoch den Wert als String in Hochkommas, wandelt er den Eintrag vorher schon passend in BIGINT um, weil die DB feststellt, das der zu vergleichende Wert ein BIGINT ist.
Alternativ könntest du auch nach “id = 5::BIGINT” suchen, das würde das gleiche bewirken.

So, das war die lange Erklärung für das kleine Problem ]
Diese Abfrage dauert etwa 50 ms. Und es ist mir nicht klar, warum es langsam ist. Ist es halt so, oder weil die Abfrage nicht optimiert ist ?[/quote]

Da hier überall ein Index benutzt wird, würde ich mal von einem “das ist so langsam” ausgehen. Allerdings:

Wie schnell oder langsam ist denn die von dir genutzte format_url() Funktion? Damit muss ja jede Ergebniszeile zwei Mal behandelt werden.
Das zweite: Was macht kernkompetenzen_in_anwendung() genau? Damit werden ja die Ergebniszeilen verglichen.

Ich habe ausprobiert, einfach ohne die Funktionen durchzuführen, spricht :

select kk_view.* from kk_view join firma_kernkompetenzen on kk_view.kk2id = firma_kernkompetenzen.kernkompetenzen_id where firma_kernkompetenzen.firma_id='5'

und nochmal das Analyze davon :

Nested Loop  (cost=0.00..57.96 rows=6 width=52)
  ->  Nested Loop  (cost=0.00..34.99 rows=5 width=34)
        ->  Index Scan using fki_firma_kernkompetenzen_firma_id on firma_kernkompetenzen  (cost=0.00..16.62 rows=4 width=8)
              Index Cond: (firma_id = 5::bigint)
        ->  Index Scan using kernkompetenzen_pkey on kernkompetenzen kk2  (cost=0.00..4.58 rows=1 width=34)
              Index Cond: (kk2.id = "outer".kernkompetenzen_id)
  ->  Index Scan using kernkompetenzen_pkey on kernkompetenzen kk1  (cost=0.00..4.58 rows=1 width=26)
        Index Cond: (kk1.id = "outer".par_id)

Aber es braucht immer noch etwa 50 ms. Die Maschine selbst ist super schnell, es ist ein Multiprozessor Server. Also von der Maschine her müsste es eigentlich glatt laufen.
Kann es damit zusammenhängen, dass die Tabelle firma_kernkompetenzen 75570 Einträge hat ?

Kann, keine Ahnung konkret.

VACUUM & VACUUM ANALYZE mal laufen lassen?

Ändert sich die Tabelle häufig, ist die Datenbank unter Last oder im Leerlauf?

Was stört dich an 50 ms? Ist doch eigentlich recht flott bei der Datenmenge, oder?