forked frompostgres/postgres
- Notifications
You must be signed in to change notification settings - Fork6
Commit2ab57e0
committed
Rewrite the key-combination logic in GIN's keyGetItem() and scanGetItem()
routines to make them behave better in the presence of "lossy" index pointers.The previous coding was outright incorrect for some cases, as recentlyreported by Artur Dabrowski: scanGetItem would fail to return index entries incases where one index key had multiple exact pointers on the same page asanother key had a lossy pointer. Also, keyGetItem was extremely inefficientfor cases where a single index key generates multiple "entry" streams, such asan @@ operator with a multiple-clause tsquery. The presence of a lossy pagepointer in any one stream defeated its ability to use the opclassconsistentFn, resulting in probing many heap pages that didn't really need tobe visited. In Artur's example case, a query likeWHERE tsvector @@ to_tsquery('a & b')was about 50X slower than the theoretically equivalentWHERE tsvector @@ to_tsquery('a') AND tsvector @@ to_tsquery('b')The way that I chose to fix this was to have GIN call the consistentFntwice with both TRUE and FALSE values for the in-doubt entry stream,returning a hit if either call produces TRUE, but not if they both returnFALSE. The code handles this for the case of a single in-doubt entry stream,but punts (falling back to the stupid behavior) if there's more than one lossyreference to the same page. The idea could be scaled up to deal with multiplelossy references, but I think that would probably be wasted complexity. Atleast to judge by Artur's example, such cases don't occur often enough to beworth trying to optimize.Back-patch to 8.4. 8.3 did not have lossy GIN index pointers, so notsubject to these problems.1 parent8a4dc94 commit2ab57e0