Puedo estar haciendo una pregunta incorrecta en el título. Aquí están los hechos:
Mi gente de servicio al cliente se ha estado quejando de los tiempos de respuesta lentos al realizar búsquedas de clientes en la interfaz de administración de nuestro sitio basado en Django.
Estamos usando Postgres 8.4.6. Comencé a registrar consultas lentas y descubrí a este culpable:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
Esta consulta tarda más de 32 segundos en ejecutarse. Aquí está el plan de consulta proporcionado por EXPLAIN:
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 Django ORM a partir de un Django QuerySet generado por la aplicación Django Admin, no tengo ningún control sobre la consulta en sí. Un índice parece ser la solución lógica. Intenté crear un índice para acelerar esto, 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?
Ese índice no va a ayudar debido al '%' al comienzo de su coincidencia: un índice BTREE solo puede coincidir con prefijos y el comodín al comienzo de su consulta significa que no hay un prefijo fijo que buscar.
Es por eso que está haciendo un escaneo de tabla y haciendo coincidir cada registro a su vez con la cadena de consulta.
Probablemente necesite ver el uso de un índice de texto completo y los operadores de coincidencia de texto en lugar de hacer la búsqueda de subcadenas con LIKE que es en este momento. Puede encontrar más información sobre la búsqueda de texto completo en la documentación:
http://www.postgresql.org/docs/8.4/static/textsearch-intro.html
De hecho, noto en esa página que LIKE aparentemente nunca usa índices, lo que me parece extraño ya que debería ser capaz de resolver prefijos que no sean comodines usando un índice BTREE. Sin embargo, algunas pruebas rápidas sugieren que la documentación probablemente sea correcta, en cuyo caso ninguna cantidad de indexación ayudará cuando esté usando LIKE para resolver la consulta.
fuente
%
es una característica necesaria: los representantes de servicio al cliente lo necesitan para encontrar cuentas de clientes, especialmente cuando hay un error tipográfico en la dirección de correo electrónico.