Pregunta

se me puede hacer la pregunta equivocada en el título. Estos son los hechos:

Mis popular servicio al cliente se han quejado de los tiempos de respuesta lentos al hacer búsquedas de los clientes en la interfaz de administración de nuestro sitio basado en Django.

Estamos utilizando PostgreSQL 8.4.6. Empecé el registro de consultas lentas, y descubrí este culpable:

SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')

Esta consulta está tomando más de 32 segundos para correr. Aquí está el plan de consulta proporcionada por explico:

QUERY PLAN
Aggregate  (cost=205171.71..205171.72 rows=1 width=0)
  ->  Seq Scan on auth_user  (cost=0.00..205166.46 rows=2096 width=0)
        Filter: (upper((email)::text) ~~ '%DEYK%'::text)

Debido a que esta es una consulta generada por el ORM de Django Django de un QuerySet generado por la aplicación de administración de Django, no tiene ningún control sobre la propia consulta. Un índice parece ser la solución lógica. He intentado crear un índice para acelerar este proceso, pero no ha hecho una diferencia:

CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))

¿Qué estoy haciendo mal? ¿Cómo puedo acelerar esta consulta?

¿Fue útil?

Solución

No hay soporte para el índice de LIKE / ILIKE en PostgreSQL 8.4 - a excepción de dejó anclada búsqueda términos.

Desde PostgreSQL 9.1 el módulo adicional pg_trgm proporciona clases de operador para los índices de ginebra y de trigramas GiST apoyo LIKE / ILIKE o expresiones regulares (operadores ~ y amigos). Instalar una vez por la base de datos:

CREATE EXTENSION pg_trgm;

Ejemplo índice GIN:

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

Relacionado:

Otros consejos

Este índice no va a ayudar a causa de la '%' en el inicio de su partido - un índice BTREE sólo puede coincidir con prefijos y el comodín en el inicio de sus medios de consulta no está fijado ningún prefijo a buscar.

Es por eso que está haciendo un recorrido de tabla y combinar todos los registros a su vez contra la cadena de consulta.

Es probable que tenga que buscar en el uso de un índice de texto completo y los operadores de texto coincidente en lugar de hacer la búsqueda subcadena con LIKE que son en este momento. Puede encontrar más en la búsqueda de texto completo en la documentación:

http://www.postgresql.org/docs/8.4/static/textsearch-intro .html

En aviso hecho de que de esa página que al igual que al parecer nunca utiliza los índices, lo que me parece extraño, ya que debe ser capaz de resolver los prefijos no comodín utilizando un índice BTREE. Unas pruebas rápidas sugiere que la documentación es probablemente correcta, sin embargo, en cuyo caso ninguna cantidad de indexación va a ayudar mientras esté usando LIKE para resolver la consulta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top