2012-12-11 3 views
7

ich meine eigenen Vergleichsoperator auf dem Text-Datentyp erstellt, die natürliche Ordnung (‚1‘ < ‚2‘ < ‚10‘ < ‚11‘ usw.) verwendet, meine neue Operatoren #<#, #<=#, #># und #>=#.Operatorklasse erstellen Muster für wie text_pattern_ops passenden

Jetzt lege ich sie in eine Operatorklasse in der Lage sein, einen Index auf sie, wie diese zu erstellen:

CREATE OPERATOR CLASS text_natsort_ops 
    FOR TYPE text USING btree AS 
    OPERATOR 1 #<#, 
    OPERATOR 2 #<=#, 
    OPERATOR 3 =, 
    OPERATOR 4 #>=#, 
    OPERATOR 5 #>#, 
    FUNCTION 1 bttext_natsort_cmp(text, text); 

Allerdings, wenn ich einen Index mit meinem neuen text_natsort_ops erstellen, das nicht in Abfragen verwendet wird einschließlich like wie es gemacht wird, wenn die text_pattern_ops verwendet werden.

Wie deklariere ich meine Operatorklasse, damit like meinen Index verwenden kann?

UPDATE:

Das scheint oben zu arbeiten, so dass die Frage ist ungültig. Mein wirkliches Problem war, dass ich eine Abfrage wie verwendet:

select * 
    from mytable 
where number like 'edi%' 
order by number using #<# 
limit 10 

und ich hatte auch einen anderen Index text_pattern_ops verwenden, die vom Planer gewählt wurde, weil es viel schneller zu arbeiten scheint. Wegen der order by ... using wird jedoch nur der Index, der meine neuen Ops verwendet, nützlich sein ... der andere Index gibt zu viele Ergebnisse zurück, und ich brauche die Limit-Klausel, die für den Index-Scan verfügbar ist.

+2

Sie sollten Ihr Update als Antwort veröffentlichen, so dass dieses Q nicht als "unbeantwortet" lauert. –

Antwort

0

Das oben genannte scheint zu funktionieren, also ist die Frage ungültig. Mein wirkliches Problem war, dass ich eine Abfrage wie verwendet:

select * 
    from mytable 
where number like 'edi%' 
order by number using #<# 
limit 10 

und ich hatte auch einen anderen Index text_pattern_ops verwenden, die vom Planer gewählt wurde, weil es viel schneller zu arbeiten scheint. Wegen der Reihenfolge, in der ... nur der Index verwendet wird, der meine neuen Ops verwendet, wird es nützlich sein ... der andere Index gibt zu viele Ergebnisse zurück, und ich brauche die Limit-Klausel, um für den Index-Scan verfügbar zu sein.

0

Ich glaube nicht, dass das möglich ist. Sie müssen darüber nachdenken, was Sie tun und warum das nicht funktioniert. Entweder haben Sie einen Index, der eine Präfix-Suche unterstützt oder etwas, das eine Suche nach einem natürlichen Zahlenbereich unterstützt. Sie können keinen btree-Index haben, der beides unterstützt.

Betrachten Sie so etwas wie:

SELECT * FROM foo 
WHERE bar like '10%' 
ORDER BY bar USING #>#; 

Ihr Problem ist, dass Ihre beiden Indizes nicht den Auftrag haben, die übereinstimmen. Der Index für die Verwendung mit LIKE wird 101, 101000, 101001, usw. gehen, während der Index für Ihre Bestellung wird gehen 10, 11, 12, 13 ... 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, ...

Da Ihre Bestellung eine andere Suchreihenfolge erfordert, gibt es keine Möglichkeit, denselben Index für beide zu verwenden. Irgendwann, wenn PostgreSQL physische Ordnungssuche von Indizes erlaubt, wird dies möglich, aber solange Indizes nur logische Reihenfolge sind, glaube ich nicht, dass das funktionieren kann.

2

einen Blick auf die PostgreSQL Präfix Erweiterung bei https://github.com/dimitri/prefix Auch sie ihre eigenen OPERATOR CLASS definieren und sagen PostgreSQL spezielle GIST-Indizes für bestimmte Operatoren zu verwenden, Vielleicht brauchen Sie etwas ähnliches?

CREATE OPERATOR CLASS gist_prefix_range_ops DEFAULT FOR TYPE prefix_range USING gist ... 
Verwandte Themen