2008-11-21 54 views

Respuesta

60

Suponiendo que pregunta por la característica común de "indización de índice" que se encuentra en muchas bases de datos, PostgreSQL no proporciona dicha función. Esta fue una decisión consciente hecha por el equipo de PostgreSQL. Puede encontrar una buena descripción de por qué y qué puede hacer en su lugar here. Las razones son, básicamente, que es un truco de rendimiento que tiende a causar más problemas más adelante en la medida en que los datos cambian, mientras que el optimizador de PostgreSQL puede volver a evaluar el plan en función de las estadísticas. En otras palabras, lo que podría ser un buen plan de consulta hoy probablemente no sea un buen plan de consulta para todos los tiempos, y las sugerencias de índice fuerzan un plan de consulta particular para todos los tiempos.

Como un martillo muy contundente, útil para las pruebas, puede utilizar los parámetros enable_seqscan y enable_indexscan. Ver:

Estos son no es adecuado para su uso en producción en curso. Si tiene problemas con la elección del plan de consulta, debe ver the documentation for tracking down query performance issues. No solo defina enable_ params y aléjese.

A menos que tenga una muy buena razón para usar el índice, Postgres puede estar haciendo la elección correcta. ¿Por qué?

  • Para las tablas pequeñas, es más rápido realizar escaneos secuenciales.
  • Postgres no usa índices cuando los tipos de datos no coinciden correctamente, puede que necesite incluir moldes adecuados.
  • Es posible que la configuración de su planificador esté causando problemas.

Véase también this old newsgroup post.

+4

acuerdo, Forzar postgres a hacerlo a tu manera general que significa lo he hecho mal 9/10 veces el planificador superará cualquier cosa que se le ocurra. El otro 1 vez es porque lo hiciste mal. –

+0

Creo que es una buena idea para verificar realmente las clases de operadores de su retención de índice. – metdos

+2

Odio revivir una vieja pregunta, pero a menudo veo en la documentación de Postgres, en las discusiones y aquí, pero ¿hay un concepto generalizado para lo que califica para una * pequeña mesa *? ¿Es algo así como 5000 filas, o 50000, etc.? – waffl

0

El producto de servidor avanzado PostgresPlus de EnterpriseDB admite la sintaxis de sugerencias de Oracle, aunque ese producto no es gratuito.

9

La pregunta en sí misma es muy inválida. Forzar (haciendo enable_seqscan = off por ejemplo) es una muy mala idea. Puede ser útil verificar si será más rápido, pero el código de producción nunca debe usar tales trucos.

En su lugar, explique el análisis de su consulta, léala y descubra por qué PostgreSQL elige el plan incorrecto (en su opinión).

Hay herramientas en la web que ayudan a leer la salida de explicar analizar - una de ellas es explain.depesz.com - escrita por mí.

Otra opción es unir el canal #postgresql en freenode irc network, y hablar con muchachos para que lo ayuden, ya que optimizar la consulta no es una cuestión de "hacer una pregunta, obtener una respuesta feliz". es más como una conversación, con muchas cosas por verificar, muchas cosas por aprender.

+0

Las listas de correo también son un excelente lugar para obtener ayuda. – jpmc26

44

Probablemente la única razón válida para el uso de

set enable_seqscan=false 

es cuando se está escribiendo consultas y quiere ver rápidamente lo que el plan de consulta sería en realidad estaban allí grandes cantidades de datos en la tabla (s). O, por supuesto, si necesita confirmar rápidamente que su consulta no utiliza un índice simplemente porque el conjunto de datos es demasiado pequeño.

+36

esta breve respuesta en realidad da una buena pista para fines de prueba – dwery

+2

¡Nadie está respondiendo la pregunta! –

+0

@IvailoBardarov La razón por la que todas estas otras sugerencias están aquí es porque PostgreSQL no tiene esta característica; esta fue una decisión consciente tomada por los desarrolladores en función de cómo se usa habitualmente y de los problemas a largo plazo que causa. – jpmc26

7

A veces, PostgreSQL falla al hacer la mejor elección de índices para una condición en particular. Como ejemplo, supongamos que hay una tabla de transacciones con varios millones de filas, de las cuales hay varios cientos para un día determinado, y la tabla tiene cuatro índices: transaction_id, client_id, date y description. ¿Desea ejecutar la siguiente consulta:

SELECT client_id, SUM(amount) 
FROM transactions 
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND 
     description = 'Refund' 
GROUP BY client_id 

PostgreSQL puede optar por utilizar el transactions_description_idx índice en lugar de transactions_date_idx, lo que puede conducir a la consulta de tomar varios minutos en lugar de menos de un segundo. Si este es el caso, puede forzar el uso del índice de la fecha por esquivar la condición de la siguiente manera:

SELECT client_id, SUM(amount) 
FROM transactions 
WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND 
     description||'' = 'Refund' 
GROUP BY client_id 
0

Hay una marca para empujar postgres a preferir un SeqScan la adición de un OFFSET 0 en la subconsulta

Este es útil para optimizar solicitudes que vinculen tablas grandes/grandes cuando en realidad solo está buscando los primeros elementos.

Digamos que está buscando los primeros/últimos 20 elementos que implican varias tablas con 100k (o más) entradas, no se construyen puntos/vinculando toda la consulta sobre todos los datos cuando lo que se busca está en el primeras 100 o 1000 entradas. En este escenario, por ejemplo, resulta ser más de 10 veces más rápido realizar un escaneo secuencial.

ver How can I prevent Postgres from inlining a subquery?

Cuestiones relacionadas