Para cada versión de Postgres que admite la indexación hash , hay una advertencia o nota de que los índices hash son "similares o más lentos" o "no mejores" que los índices btree , al menos hasta la versión 8.3. De los documentos:
Nota: Debido a la utilidad limitada de los índices hash, generalmente se debe preferir un índice de árbol B sobre un índice hash. No tenemos evidencia suficiente de que los índices hash sean realmente más rápidos que los árboles B, incluso para las comparaciones =. Además, los índices hash requieren bloqueos más gruesos; ver la Sección 9.7.
Nota: Las pruebas han demostrado que los índices de hash de PostgreSQL son similares o más lentos que los índices de árbol B, y el tamaño del índice y el tiempo de creación de los índices de hash es mucho peor. Los índices de hash también sufren un bajo rendimiento con alta concurrencia. Por estas razones, se desaconseja el uso del índice hash.
Nota: Las pruebas han demostrado que los índices hash de PostgreSQL no funcionan mejor que los índices B-tree, y el tamaño del índice y el tiempo de construcción de los índices hash es mucho peor. Además, las operaciones de índice hash no están actualmente registradas en WAL, por lo que es posible que sea necesario reconstruir los índices hash con REINDEX después de un bloqueo de la base de datos. Por estas razones, actualmente no se recomienda el uso del índice hash.
En este hilo de la versión 8.0 , afirman que nunca había encontrado un caso en el que los índices hash fueran realmente más rápidos que btree.
Incluso en la versión 9.2, la ganancia de rendimiento para cualquier otra cosa que no sea escribir el índice real no fue casi nada según esta publicación de blog (14 de marzo de 2016):
Hash Indexes on Postgres de André Barbosa.
Mi pregunta es ¿cómo es eso posible?
Por definición, los índices Hash son una O(1)
operación, donde un btree es una O(log n)
operación. Entonces, ¿cómo es posible que una O(1)
búsqueda sea más lenta que (o incluso similar a) encontrar la rama correcta y luego encontrar el registro correcto?
¡Quiero saber qué pasa con la teoría de la indexación!
fuente
Respuestas:
Los índices de Btree basados en disco realmente son O (log N), pero eso es prácticamente irrelevante para las matrices de discos que se ajustan a este sistema solar. Debido al almacenamiento en caché, en su mayoría son O (1) con una constante muy grande más O ((log N) -1) con una constante pequeña. Formalmente, eso es lo mismo que O (log N), porque las constantes no importan en la notación O grande. Pero sí importan en la realidad.
Gran parte de la desaceleración en las búsquedas de índice hash provino de la necesidad de proteger contra la corrupción o los puntos muertos causados por el cambio de tamaño de la tabla hash concurrente con las búsquedas. Hasta las versiones recientes (cada versión que mencionas está desactualizada), esta necesidad condujo a constantes aún más altas y a una concurrencia bastante pobre. Se emplearon muchas más horas de trabajo en la optimización de la concurrencia de BTree que en la concurrencia hash.
fuente
La búsqueda de hash es teóricamente una
O(1)
operación cuando el hash clave se asigna directamente a la ubicación física del registro de destino. La forma en que funciona en Postgres, si lo entiendo correctamente, es un poco más complicado: el hash clave se asigna a un cubo que contiene el OID que está buscando. Un depósito puede comprender potencialmente más de una página, que debe escanear secuencialmente hasta que encuentre su clave particular (hash). Es por eso que parece más lento de lo esperado.El archivo README del método de acceso al índice hash en el repositorio de código fuente tiene todos los detalles.
fuente