WIP: Covering + unique indexes.
Anastasia Lubennikova <a.lubennikova@postgrespro.ru>
Attachments
- test.sql (application/sql)
- covering_unique_1.0.patch (text/x-patch) patch
Hi hackers, I'm working on a patch that allows to combine covering and unique functionality for btree indexes. _Previous discussion was here:_ 1) Proposal thread <http://www.postgresql.org/message-id/55F2CCD0.7040608@postgrespro.ru> 2) Message with proposal clarification <http://www.postgresql.org/message-id/55F84DF4.5030207@postgrespro.ru> In a nutshell, the feature allows to create index with "key" columns and "included" columns. "key" columns can be used as scan keys. Unique constraint relates only to "key" columns. "included" columns may be used as scan keys if they have suitable opclass. Both "key" and "included" columns can be returned from index by IndexOnlyScan. Btree is the default index and it's used everywhere. So it requires properly testing. Volunteers are welcome) _Use case:_ - We have a table (c1, c2, c3, c4); - We need to have an unique index on (c1, c2). - We would like to have a covering index on all columns to avoid reading of heap pages. Old way: CREATE UNIQUE INDEX olduniqueidx ON oldt USING btree (c1, c2); CREATE INDEX oldcoveringidx ON oldt USING btree (c1, c2, c3, c4); What's wrong? Two indexes contain repeated data. Overhead to data manipulation operations and database size. New way: CREATE UNIQUE INDEX newidx ON newt USING btree (c1, c2) INCLUDING (c3, c4); The patch is attached. In 'test.sql' you can find a test with detailed comments on each step, and comparison of old and new indexes. New feature has following syntax: CREATE UNIQUE INDEX newidx ON newt USING btree (c1, c2) INCLUDING (c3, c4); Keyword INCLUDING defines the "included" columns of index. These columns aren't concern to unique constraint. Also, them are not stored in index inner pages. It allows to decrease index size. _Results:_ 1) Additional covering index is not required anymore. 2) New index can use IndexOnlyScan on queries, where old index can't. For example, explain analyze select c1, c2 from newt where c1<10000 and c3<20; *more examples in 'test.sql' _Future work:_ To do opclasses for "included" columns optional. CREATE TABLE tbl (c1 int, c4 box); CREATE UNIQUE INDEX idx ON tbl USING btree (c1) INCLUDING (c4); If we don't need c4 as an index scankey, we don't need any btree opclass on it. But we still want to have it in covering index for queries like SELECT c4 FROM tbl WHERE c1=1000; SELECT * FROM tbl WHERE c1=1000; -- Anastasia Lubennikova Postgres Professional:http://www.postgrespro.com The Russian Postgres Company
Commits
-
Adjust INCLUDE index truncation comments and code.
- 075aade4361b 11.0 landed
-
Add commentary explaining why MaxIndexTuplesPerPage calculation is safe.
- 2a67d6440db4 11.0 cited
-
Indexes with INCLUDE columns and their support in B-tree
- 8224de4f42cc 11.0 landed
-
Add amcheck verification of heap relations belonging to btree indexes.
- 7f563c09f890 11.0 cited
-
Doc: move info for btree opclass implementors into main documentation.
- 3785f7eee3d9 11.0 cited
-
Doc: mention that you can't PREPARE TRANSACTION after NOTIFY.
- e4fbf22831c2 11.0 cited
-
Remove dedicated B-tree root-split record types.
- 0c504a80cf2e 11.0 cited
-
Restructure index access method API to hide most of it at the C level.
- 65c5fcd353a8 9.6.0 cited
-
Split _bt_insertonpg to two functions.
- bc292937ae6a 8.3.0 cited
-
Major overhaul of btree index code. Eliminate special BTP_CHAIN logic for
- 9e85183bfc31 7.1.1 cited