Umlaute und Performance?

Hallo,
in der Doku ist zu lesen dass wenn die locales gesetzt werden, bzw. andere locales als C zum Einsatz kommen dies einen “performance impact” zur Folge hat.

Bezieht sich dieser impact “nur” auf die beiden genannten Sachen oder ist da noch mit mehr Performanceeinbußen zu rechnen?

It slows character handling and prevents ordinary indexes from being used by LIKE.

Kann mir da jemand genaueres drüber sagen, weil wenn jetzt in einer DB viel mit Namen und Umlauten und sonstigem hantiert wird, ist das ja nicht unbedingt toll wenn man da Performance verschenkt die man evtl. haben möchte. Allerdings ist die falsche Ausgabe von sortierten Abfragen natürlich auch nicht sehr schön.

Wie wird sowas in der Praxis gehandhabt? Mein erster Gedanke war ja die DB so schnell zu lassen wie sie kann, und evtl. Fehler in der Sortierung bei Umlauten o.ä. dann auf Anwendungsebene zu bearbeiten. Auch nicht wirklich toll, da dies auch wieder mit zusätzlichen Operationen verbunden ist. Also bezahlt man im Prinzip egal wo den Preis für die Verwendung von Umlauten, insbesondere bei Webanwendungen wo der Server unter Umständen sowieso schon genug zu tun hat.

Gruss

Daniel

Hallo,

welche anderen Locale willst Du denn einsetzen?


The drawback of > using locales > other than > C > or > POSIX > > in PostgreSQL is its performance impact. It slows character handling and prevents ordinary indexes from being used by > LIKE> . For this reason use locales only if you actually need them.


mfg

fristo

Ich brauche für LC_COLLATE und LC_CTYPE => de_DE. Wenn ich C oder POSIX nutze stimmt order by eben nicht. lower() und upper() funktionieren auch nicht auf Umlauten.
Ist halt ziemlich blöd, oder man muss sich eben andere Massnahmen überlegen um das zu handeln. Aber das sollte ja eigentlich in einer DB zu erledigen sein. Bzw. erledigt werden. Was es ja auch kann, aber eben nur mit den anderen locales und dem Verzicht auf den Index. Eben die Funktionen wie hier beschrieben.

Nur wenn das wirklich so ist, ist das ja ein immenses Manko von postgresql, oder seh ich da was falsch? Deswegen auch die Frage wie sowas in der Praxis oder von euch gehandhabt wird.

Gruß

Daniel

Ich glaube, du tust da etwas massiv überbewerten. Wenn Du in der DB Performance-Probleme hast, dann kann das an vielen Dingen liegen, aber sehr unwahrscheinlich an der Wahl des Encodings.

Andreas

Was heisst jetzt massiv überbewerten. Hier mal die Zahlen zum Vergleich:

[I]show LC_COLLATE[/I]
=> "de_DE"

[I]explain analyze select * from person where nachname like 'Bö%'[/I]
"Seq Scan on person  (cost=0.00..3264.69 rows=399 width=570) (actual time=0.219..258.915 rows=24 loops=1)"
"  Filter: ((nachname)::text ~~ 'Bö%'::text)"
"Total runtime: 259.178 ms"



[I]show LC_COLLATE[/I]
=> "C"

[I]explain analyze select * from person where nachname like 'Bö%'[/I]

"Bitmap Heap Scan on person  (cost=5.39..1034.79 rows=399 width=570) (actual time=0.177..0.339 rows=24 loops=1)"
"  Filter: ((nachname)::text ~~ 'Bö%'::text)"
"  ->  Bitmap Index Scan on index_person_on_nachname  (cost=0.00..5.39 rows=399 width=0) (actual time=0.124..0.124 rows=24 loops=1)"
"        Index Cond: (((nachname)::text >= 'Bö'::character varying) AND ((nachname)::text < 'B÷'::character varying))"
"Total runtime: 0.571 ms"

Das ist jetzt eine Abfrage über eine kleine Tabelle mit ~80000 Datensätzen.
Man nenne mich kleinkarriert oder überbewertet, aber eine Laufzeit von 0,571 ms : 259,178 ms finde ich bei so einer kleinen Tabelle schon mehr als deutlich. Was dann bei grossen Tabellen passiert sollte wohl klar sein.

Fällt das immer noch unter überbewertet, oder wie seht ihr das mit den Zahlen so? Das Problem ist eben dass der Index nicht genutzt wird sobald LC_LOCATE eben auf de_DE steht.

Wenn das Problem ja über die in der Doku beschriebenen Operator Classes in den Griff zu bekommen wäre, wäre das ja mal ok. Allerdings weiss ich da nicht so genau wie das anzuwenden wäre.

Interessiert ich aber jetzt mal aufjedenfall was ihr zu den Zahlen sagt.

Gruß

Seq-Scan versus Index-Scan

Fällt das immer noch unter überbewertet, oder wie seht ihr das mit den Zahlen so? Das Problem ist eben dass der Index nicht genutzt wird sobald LC_LOCATE eben auf de_DE steht.

Gruß

Lösbares Problem. Erstelle den Index mit Option varchar_pattern_ops, dann klappt das auch mit Umlauten. Ich bin grad zu stark in Feierstimmung (siehe anderes Posting von mir heute), um da jetzt näher drauf eingehen zu wollen… frag Google nach varchar_pattern_ops und Verwandten.

Andreas



test=*# show LC_COLLATE;
 lc_collate
------------
 de_DE
(1 row)


test=*# \d words
   Table "public.words"
 Column | Type | Modifiers
--------+------+-----------
 w      | text |
Indexes:
    "idx_words" btree (lower(w) varchar_pattern_ops)

test=*# explain analyse select * from words where lower(w) ~ '^bö';
                                                     QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
 Index Scan using idx_words on words  (cost=0.01..6.01 rows=284 width=12) (actual time=0.066..0.066 rows=0 loops=1)
   Index Cond: ((lower(w) ~>=~ 'bö'::character varying) AND (lower(w) ~<~ 'b÷'::character varying))
   Filter: (lower(w) ~ '^bö'::text)
 Total runtime: 0.207 ms
(4 rows)

test=*# select count(1) from words ;
 count
-------
 56840
(1 row)

Andreas

Jep, das mit den varchar_pattern_ops hatte ich irgendwie falsch verstanden.
Nachdem ich den Index damit angelegt hatte funktionierte es wie erwartet.
Danke für den Hinweis.

Alles Gute für dich und den Nachwuchs im übrigen. :slight_smile:

Kleiner Linktipp dazu noch: » Blog Archive » indexable ” field like ‘%something’”

Alles Gute für dich und den Nachwuchs im übrigen. > :slight_smile: >

Danke :wink:

Andreas