¿Por qué indexarías text_pattern_ops en una columna de texto?

18

Hoy Seven Databases en Seven Weeks me presentó los índices por operador.

Puede indexar cadenas para patrones que coincidan con las consultas anteriores creando un text_pattern_opsíndice de clase de operador, siempre que los valores se indexen en minúsculas.

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

Usamos el text_pattern_opsporque el título es de tipo texto. Si necesita índice varchars, caracteres, o nombres, utilice las operaciones relacionadas: varchar_pattern_ops, bpchar_pattern_ops, y name_pattern_ops.

El ejemplo me parece realmente confuso. ¿Por qué es útil hacer esto?

Si la columna es texto de tipo, ¿los otros tipos (varchar, char, name) no se convertirán en texto antes de usarse como valor de búsqueda?

¿Cómo se comporta ese índice de manera diferente al que usa el operador predeterminado?

CREATE INDEX moves_title_pattern ON movies (lower(title));
Iain Samuel McLean Anciano
fuente
1
Esta pregunta relacionada puede ser de ayuda: dba.stackexchange.com/questions/10694/…
Erwin Brandstetter
Gracias Erwin Su respuesta a esa pregunta fue muy útil cuando investigó las ideas del libro.
Iain Samuel McLean Élder

Respuestas:

20

La documentación a menudo le da una respuesta a tales preguntas. Como en este caso , también:

Las clases de operador text_pattern_ops, varchar_pattern_ops y bpchar_pattern_ops admiten índices de árbol B en los tipos text, varchar y char respectivamente. La diferencia con las clases de operador predeterminadas es que los valores se comparan estrictamente carácter por carácter en lugar de acuerdo con las reglas de clasificación específicas de la localidad. Esto hace que estas clases de operador sean adecuadas para su uso en consultas que involucran expresiones de coincidencia de patrones (expresiones regulares LIKE o POSIX) cuando la base de datos no usa la configuración regional "C" estándar. Como ejemplo, puede indexar una columna varchar como esta:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

Tenga en cuenta que también debe crear un índice con la clase de operador predeterminada si desea consultas que incluyan comparaciones ordinarias <, <=,> o> = para usar un índice. Dichas consultas no pueden usar las clases de operador xxx_pattern_ops . (Sin embargo, las comparaciones de igualdad ordinarias pueden usar estas clases de operadores). Es posible crear múltiples índices en la misma columna con diferentes clases de operadores.

La documentación continúa diciendo:

Si usa la configuración regional C, no necesita las clases de operador xxx_pattern_ops, porque un índice con la clase de operador predeterminada es utilizable para consultas de coincidencia de patrones en la configuración regional C.

Puede verificar su configuración regional de la siguiente manera (es probable que sea UTF8 en lugar de "C"):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8
dezso
fuente
¡Ajá! Leí eso, pero me resultó difícil seguirlo, así que no lo entendí. ¿Diría que la utilidad útil de text_pattern_opsdepende de la configuración regional? Parece que me beneficiaría porque mi configuración regional es 'en_US.UTF-8' (no 'C'), por lo que las consultas de patrones no pueden usar el índice predeterminado.
Iain Samuel McLean Élder
Exactamente. Agregaría (pero esto es solo especulación) que con los datos que permanecen dentro de los caracteres ASCII básicos, la clase de operador predeterminada es igual de buena, al menos veo consultas con LIKE 'something%' usando tales índices.
dezso
55
@dezso: si ha visto una LIKEconsulta usando un índice b-tree simple, entonces el db debe estar usando la Cconfiguración regional. O el índice se define con COLLATE "POSIX"(o COLLATE "C") y la consulta especifica una coincidencia COLLATION. Con cualquier otra clasificación, el orden del índice no coincide con las reglas locales y, por lo tanto, no se puede utilizar para la coincidencia de patrones.
Erwin Brandstetter
1
@ErwinBrandstetter Tengo que confirmar que tienes razón.
dezso
1
@StopHarmingMonica obtienes la respuesta correcta (y sin error), solo la consulta será posiblemente más lenta, no pudiendo usar el índice.
dezso