postgresql - not - La comprensión de postgres explica w/análisis de montón/índice de mapa de bits
psql tutorial (2)
Tengo una mesa con 4.5 millones de filas. No hay clave principal. La tabla tiene una columna p_id
, tipo entero. Hay un índice, idx_mytable_p_id
en esta columna que utiliza el método btree
. Hago:
SELECT * FROM mytable WHERE p_id = 123456;
Ejecuto una explicación sobre esto y veo el siguiente resultado:
Bitmap Heap Scan on mytable (cost=12.04..1632.35 rows=425 width=321)
Recheck Cond: (p_id = 543094)
-> Bitmap Index Scan on idx_mytable_p_id (cost=0.00..11.93 rows=425 width=0)
Index Cond: (p_id = 543094)
Preguntas:
- ¿Por qué esa consulta realiza un escaneo de montón y luego un escaneo de índice de mapa de bits?
- ¿Por qué está examinando 425 filas? ¿Por qué el ancho de la operación es 321?
- ¿Cuánto me cuesta 12.04..1632.35 y 0.00..11.93?
Para el registro hay 773 filas con el valor p_id de 123456. Hay 38 columnas en mytable
.
¡Gracias!
¿Por qué esa consulta realiza un escaneo de montón y luego un escaneo de índice de mapa de bits?
No es exactamente La salida EXPLAIN muestra la estructura de los nodos de ejecución, con los que están en el nivel "más alto" (sin sangría hasta el momento) extrayendo filas de los nodos debajo de ellos. Por lo tanto, cuando el nodo Bitmap Heap Scan va a extraer su primera fila, la Exploración del Índice de Bitmap se ejecuta para determinar el conjunto de filas que se utilizarán, y pasa información en la primera fila al escaneo de Heap. La exploración de índice pasa el índice para determinar qué filas deben leerse, y la exploración de pila realmente las lee. La idea es que al leer el montón de principio a fin en lugar de hacerlo en orden de índice, tendrá menos acceso aleatorio: todas las filas coincidentes de una página determinada se leerán cuando se cargue esa página, y se podrán leer suficientes páginas para utilice un acceso secuencial más económico en lugar de ir y venir por todo el disco.
¿Por qué está examinando 425 filas?
No es. Ejecutó EXPLAIN, que solo muestra sus estimaciones y el plan elegido, en realidad no examina las filas en absoluto. Eso hace que el valor de EXPLAIN sea bastante limitado en comparación con ejecutar EXPLAIN ANALYZE, que realmente ejecuta la consulta y le muestra las estimaciones y los números reales .
¿Por qué el ancho de la operación es 321?
Aparentemente ese es el tamaño, en bytes, de las tuplas en mytable
.
¿Cuánto me cuesta 12.04..1632.35 y 0.00..11.93?
El primer número es el costo para devolver la primera fila desde ese nodo; el segundo número es el costo de devolver todas las filas para ese nodo. Recuerde, estas son estimaciones. La unidad es una unidad de costo abstracto. El número absoluto no significa nada; lo que importa en la planificación es qué plan tiene el costo más bajo. Si está usando un cursor, importa el primer número; de lo contrario, suele ser el segundo número. (Creo que interpola para una cláusula LIMIT.)
A menudo es necesario ajustar los factores de costo configurables, tales como random_page_cost
y cpu_tuple_cost
, para modelar con precisión los costos dentro de su entorno. Sin estos ajustes, es probable que los costos comparativos no coincidan con los tiempos de ejecución correspondientes, por lo que se podría elegir un plan menos que óptimo.
re 1) los planes de ejecución deben leerse desde el nodo más interno al nodo más externo. Primero, hacer un escaneo de índice (para encontrar las filas) y acceder a la tabla real para devolver las filas que encontró el escaneo de índice
re 2) el número de filas que se muestran en el plan es solo una estimación basada en las estadísticas y, como tal, 425 vs. 773 suena bastante razonable. Si quiere ver cifras reales , use explain analyze
re 3) el primer número en la figura del costo es el costo de "inicio" para iniciar el paso del planificador, el segundo costo es el costo total de ese paso.
Todo esto está documentado en el manual: http://www.postgresql.org/docs/current/static/using-explain.html
Es posible que desee ir a través de estos enlaces en la Wiki de PostgreSQL también: