Improve HNSW index build performance more (#295)

This takes the approach from commit a713e2acaa further. Once we have
remove a candidate from the "closer" set, we still don't need to
recalculate everything that follows. Any candidates that were in the
closer set before still only need to be compared with any new
candidates that we have added.
This commit is contained in:
Heikki Linnakangas
2023-10-06 02:04:50 +03:00
committed by GitHub
parent a713e2acaa
commit c81302b835

View File

@@ -755,7 +755,8 @@ SelectNeighbors(List *c, int m, int lc, FmgrInfo *procinfo, Oid collation, HnswE
List *w = list_copy(c);
pairingheap *wd;
bool mustCalculate = !e2->neighbors[lc].closerSet;
bool foundNew = false;
List *added = NIL;
bool removedAny = false;
if (list_length(w) <= m)
return w;
@@ -772,24 +773,38 @@ SelectNeighbors(List *c, int m, int lc, FmgrInfo *procinfo, Oid collation, HnswE
/* Use previous state of r and wd to skip work when possible */
if (mustCalculate)
e->closer = CheckElementCloser(e, r, lc, procinfo, collation);
else if (foundNew)
else if (list_length(added) > 0)
{
/* If new or current candidate is not closer, no change in state */
if (newCandidate->closer && e->closer)
/*
* If the current candidate was closer, we only need to compare it
* with the other candidates that we have added.
*/
if (e->closer)
{
/* Only need to compare with new candidate */
float distance = HnswGetDistance(e->element, newCandidate->element, lc, procinfo, collation);
e->closer = e->distance < distance;
e->closer = CheckElementCloser(e, added, lc, procinfo, collation);
if (!e->closer)
mustCalculate = true;
removedAny = true;
}
else
{
/*
* If we have removed any candidates from closer, a candidate
* that was not closer earlier might now be.
*/
if (removedAny)
{
e->closer = CheckElementCloser(e, r, lc, procinfo, collation);
if (e->closer)
added = lappend(added, e);
}
}
}
else if (e == newCandidate)
{
e->closer = CheckElementCloser(e, r, lc, procinfo, collation);
foundNew = true;
if (e->closer)
added = lappend(added, newCandidate);
}
if (e->closer)