2012-12-11 11 views
7

ho creato il mio operatori di confronto sul tipo di dati testo che utilizza ordinamento naturale ('1' < '2' < '10' < '11', ecc), usando i miei nuovi operatori #<#, #<=#, #># e #>=#.Crea classe operatore per il pattern matching come text_pattern_ops

Ora li metto in una classe operatore per essere in grado di creare un indice su di loro, in questo modo:

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); 

Tuttavia, quando creo un indice usando il mio nuovo text_natsort_ops, questo non viene utilizzato nelle query Coinvolgimento di like come quando si utilizza lo text_pattern_ops.

Come dichiarare la mia classe di operatore per consentire a like di utilizzare il mio indice?

UPDATE:

È possibile che questo sembra funzionare, quindi la domanda non è valida. Il mio vero problema era che avevo una query come:

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

e ho anche avuto un altro indice utilizzando text_pattern_ops, che è stato scelto dal progettista, perché sembra funzionare molto più veloce. Tuttavia, a causa dello order by ... using, sarà utile solo l'indice che utilizza i miei nuovi ops ... l'altro indice restituisce troppi risultati e ho bisogno che la clausola limite sia disponibile per la scansione dell'indice.

+2

Dovresti postare il tuo aggiornamento come risposta, quindi questo Q non si annida come "senza risposta". –

risposta

0

Quanto sopra sembra funzionare, quindi la domanda non è valida. Il mio vero problema era che avevo una query come:

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

e ho anche avuto un altro indice utilizzando text_pattern_ops, che è stato scelto dal progettista, perché sembra funzionare molto più veloce. Tuttavia, a causa dell'ordine di ... usare solo l'indice usando i miei nuovi op sarà utile ... l'altro indice restituisce troppi risultati, e ho bisogno che la clausola limite sia disponibile per la scansione dell'indice.

0

Non penso sia possibile. Devi pensare a quello che stai facendo e perché questo non funzionerà. O avrai un indice che supporta una ricerca prefisso o qualcosa che supporti una ricerca naturale dell'intervallo numerico. Non puoi avere un indice btree che supporti entrambi.

considerare qualcosa di simile:

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

Il tuo problema è che i due indici non avranno un ordine che corrisponderà. L'indice da usare con LIKE andrà 101, 101000, 101001, ecc. Mentre l'indice per il tuo ordine andrà 10, 11, 12, 13 ... 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, ...

Poiché l'ordine richiede un ordine di ricerca diverso, non è possibile utilizzare lo stesso indice per entrambi. A un certo punto, se PostgreSQL consente la ricerca di ordini fisici degli indici, questo potrebbe diventare possibile ma fintanto che gli indici sono solo ordini logici, non penso che questo possa funzionare.

2

Dai un'occhiata alla estensione PostgreSQL prefisso AT https://github.com/dimitri/prefix Anche loro, definiscono il proprio operatore di classe e dire PostgreSQL per utilizzare gli indici speciali GIST per taluni operatori, forse avete bisogno di qualcosa di simile?

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