Perché indicizzeresti text_pattern_ops su una colonna di testo?


18

Oggi Seven Database in Seven Weeks mi ha fatto conoscere gli indici per operatore.

È possibile indicizzare le stringhe per il modello che corrisponde alle query precedenti creando un text_pattern_opsindice di classe operatore, purché i valori siano indicizzati in minuscolo.

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);

Abbiamo usato il text_pattern_opsperché il titolo è di tipo testo. Se avete bisogno di indicizzare VARCHAR, caratteri, o nomi, utilizzare i relativi ops: varchar_pattern_ops, bpchar_pattern_ops, e name_pattern_ops.

Trovo l'esempio davvero confuso. Perché è utile farlo?

Se la colonna è di tipo testo, gli altri tipi (varchar, char, name) non verrebbero inseriti nel testo prima di essere usati come valore di ricerca?

In che modo tale indice si comporta in modo diverso da quello che utilizza l'operatore predefinito?

CREATE INDEX moves_title_pattern ON movies (lower(title));

1
Questa domanda correlata può essere di aiuto: dba.stackexchange.com/questions/10694/…
Erwin Brandstetter,

Grazie Erwin. La tua risposta a questa domanda è stata molto utile durante la ricerca delle idee nel libro.
Iain Samuel McLean Elder,

Risposte:


20

La documentazione spesso fornisce una risposta a tali domande. Come in questo caso anche:

Le classi operatore text_pattern_ops, varchar_pattern_ops e bpchar_pattern_ops supportano gli indici B-tree rispettivamente sui tipi text, varchar e char. La differenza rispetto alle classi operatore predefinite è che i valori vengono confrontati rigorosamente carattere per carattere anziché secondo le regole di confronto specifiche della locale. Ciò rende queste classi di operatori adatte all'uso da parte di query che coinvolgono espressioni di corrispondenza dei modelli (espressioni regolari LIKE o POSIX) quando il database non utilizza le impostazioni internazionali "C" standard. Ad esempio, potresti indicizzare una colonna varchar in questo modo:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

Si noti che è inoltre necessario creare un indice con la classe operatore predefinita se si desidera che le query che prevedono confronti <, <=,> o> = ordinari utilizzino un indice. Tali query non possono utilizzare le classi di operatori xxx_pattern_ops . (Tuttavia, i confronti di uguaglianza ordinaria possono utilizzare queste classi di operatori.) È possibile creare più indici sulla stessa colonna con classi di operatori diverse.

La documentazione prosegue dicendo:

Se si utilizza la locale C, non sono necessarie le classi di operatore xxx_pattern_ops, poiché è possibile utilizzare un indice con la classe operatore predefinita per le query di corrispondenza dei modelli nella locale C.

Puoi controllare la tua locale come segue (è probabile che sia UTF8 anziché "C"):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8

Aha! L'ho letto, ma ho trovato difficile seguirlo, quindi non l'ho accettato. Diresti che l'utilità utile text_pattern_opsdipende dalle impostazioni locali? Sembra che mi gioverebbe perché la mia locale è 'en_US.UTF-8' (non 'C'), quindi le query di pattern non possono usare l'indice predefinito.
Iain Samuel McLean Elder,

Esattamente. Vorrei aggiungere (ma questa è solo una speculazione) che con i dati all'interno dei caratteri ASCII di base la classe operatore predefinita è altrettanto buona - almeno vedo query con LIKE "qualcosa%" che utilizza tali indici.
dezso

5
@dezso: se hai visto una LIKEquery usando un semplice indice b-tree, allora il db deve usare la Clocalizzazione. Oppure l'indice viene definito con COLLATE "POSIX"(o COLLATE "C") e la query specifica una corrispondenza COLLATION. Con qualsiasi altra fascicolazione, l'ordine dell'indice non corrisponde alle regole locali e pertanto non può essere utilizzato per la corrispondenza dei modelli.
Erwin Brandstetter,

1
@ErwinBrandstetter Devo confermare, hai ragione.
dezso

1
@StopHarmingMonica ottieni la risposta corretta (e nessun errore), solo la query sarà probabilmente più lenta, non potendo utilizzare l'indice.
dezso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.