¿Cómo es posible que Hash Index no sea más rápido que Btree para búsquedas de igualdad?


8

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:

Versión 7.2 :

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.

Versión 7.3 (y hasta 8.2) :

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.

Versión 8.3 :

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!


La discusión se ha movido al chat .
ypercubeᵀᴹ

Respuestas:


7

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.


Gracias. Soy muy consciente de cuán pasada su fecha de caducidad son esas versiones, pero todavía tenía curiosidad acerca de cómo el rendimiento estaba muy por detrás de lo que esperaba
Sampson Crowley

3

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.


así que, básicamente, un índice hash ES un tipo de índice de ramificación en lo que respecta a psql
Sampson Crowley

eso realmente tiene mucho más sentido sabiendo que usan cubos para almacenar las llaves reales
Sampson Crowley

También gracias por el enlace al archivo Léame. No tenía idea de que existían en el repositorio
Sampson Crowley

2
Las páginas de desbordamiento deben buscarse linealmente, y en el peor de los casos degenerados puede haber un número ilimitado de ellas. Pero las búsquedas dentro de una página tienen un número limitado de elementos que pueden existir en una página, por lo que son O (1) por página de desbordamiento, y usan una búsqueda binaria para que la constante tampoco sea demasiado cutre. Realmente fue la disposición para hacer que la concurrencia de las operaciones fuera segura lo que fue el cuello de botella.
jjanes

1
@AnoE: se sorprenderá ... Siempre hay una compensación entre el rendimiento y el [desperdicio de] recursos; en algunos casos, uno podría favorecer el rendimiento.
mustaccio
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.