Come è possibile che Hash Index non sia più veloce di Btree per le ricerche sull'uguaglianza?


8

Per ogni versione di Postgres che supportava l' indicizzazione hash , c'è un avvertimento o una nota che gli indici hash sono "simili o più lenti" o "non migliori" degli indici btree , almeno fino alla versione 8.3. Dai documenti:

Versione 7.2 :

Nota: a causa della limitata utilità degli indici hash, un indice B-tree dovrebbe generalmente essere preferito a un indice hash. Non abbiamo prove sufficienti che gli indici di hash siano effettivamente più veloci degli alberi B anche per = confronti. Inoltre, gli indici hash richiedono blocchi più grossolani; vedere la sezione 9.7.

Versione 7.3 (e fino alla 8.2) :

Nota: i test hanno dimostrato che gli indici hash di PostgreSQL sono simili o più lenti degli indici B-tree, e la dimensione dell'indice e il tempo di costruzione degli indici hash sono molto peggiori. Anche gli indici hash subiscono scarse prestazioni in caso di concorrenza elevata. Per questi motivi, l'uso dell'indice hash è scoraggiato.

Versione 8.3 :

Nota: i test hanno dimostrato che gli indici hash di PostgreSQL non funzionano meglio degli indici B-tree e la dimensione dell'indice e il tempo di costruzione degli indici hash sono molto peggiori. Inoltre, le operazioni dell'indice hash non sono attualmente registrate da WAL, pertanto potrebbe essere necessario ricostruire gli indici hash con REINDEX dopo un arresto anomalo del database. Per questi motivi, l'utilizzo dell'indice hash è attualmente sconsigliato.

In questo thread della versione 8.0 , affermano di non aver mai trovato un caso in cui gli indici di hash fossero effettivamente più veloci di btree.

Anche nella versione 9.2, il guadagno in termini di prestazioni per qualcosa di diverso dalla scrittura dell'indice reale è stato quasi nulla secondo questo post del blog (14 marzo 2016):
Hash Indexes su Postgres di André Barbosa.

La mia domanda è: come è possibile?

Per definizione, gli indici hash sono O(1)un'operazione, in cui un btree è O(log n)un'operazione. Quindi, come è possibile che una O(1)ricerca sia più lenta di (o addirittura simile a) trovare il ramo corretto e quindi trovare il record corretto?

Voglio sapere che dire della teoria dell'indicizzazione potrebbe MAI renderlo possibile!


Risposte:


7

Gli indici Btree basati su disco sono veramente O (log N), ma questo è praticamente irrilevante per gli array di dischi che si adattano a questo sistema solare. A causa della memorizzazione nella cache, sono principalmente O (1) con una costante molto grande più O ((log N) -1) con una costante piccola. Formalmente, è la stessa cosa di O (log N), perché le costanti non contano in notazione O grande. Ma contano nella realtà.

Gran parte del rallentamento delle ricerche nell'indice hash deriva dalla necessità di proteggere dalla corruzione o dai deadlock causati dal ridimensionamento della tabella hash in concomitanza con le ricerche. Fino alle versioni recenti (ogni versione citata è comicamente obsoleta), questa necessità ha portato a costanti ancora più elevate e una concorrenza piuttosto scarsa. Molte più ore di lavoro sono andate nell'ottimizzazione della concorrenza BTree rispetto alla concorrenza hash.


Grazie. Sono molto consapevole di quanto siano lontane la data di scadenza di quelle versioni, ma ero ancora curioso di sapere come le prestazioni fossero così lontane da ciò che mi sarei aspettato
Sampson Crowley,

3

La ricerca hash è teoricamente O(1)un'operazione quando l'hash chiave viene mappato direttamente nella posizione fisica del record di destinazione. Il modo in cui funziona in Postgres, se lo capisco correttamente, è un po 'più complicato: l'hash chiave si collega a un bucket che contiene l'OID che stai cercando. Un bucket può comprendere potenzialmente più di una pagina, di cui è necessario eseguire la scansione sequenziale fino a trovare la chiave specifica (hash). Ecco perché sembra più lento di quanto ti aspetti.

Il file README del metodo di accesso all'indice hash nel repository del codice sorgente contiene tutti i dettagli.


quindi sostanzialmente un indice di hash È un tipo di indice di ramificazione per quanto riguarda psql
Sampson Crowley

che in realtà ha molto più senso sapere che usano i secchi per conservare le chiavi effettive
Sampson Crowley,

grazie anche per il link al readme. Non avevo idea di quelli che esistevano nel repository
Sampson Crowley,

2
Le pagine di overflow devono essere cercate in modo lineare, e nei casi peggiori degenerati può esserci un numero illimitato di esse. Ma le ricerche all'interno di una pagina hanno un numero limitato di elementi che possono esistere su una pagina, quindi sono O (1) per pagina di overflow e usano una ricerca binaria in modo che la costante non sia troppo squallida. Era davvero la disposizione a rendere sicura la concorrenza operativa che era il collo di bottiglia.
jjanes,

1
@AnoE: rimarrai sorpreso ... C'è sempre un compromesso tra prestazioni e [spreco di] risorse; in alcuni casi si potrebbe favorire la prestazione.
Mustaccio,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.