B-tree
Ordered search
B-trees can handle equality and range queries on data that can be sorted into some ordering. In particular, the PostgreSQL query planner will consider using a B-tree index whenever an indexed column is involved in a comparison using one of these operators:
Reading PostgreSQL 18.6.
Capabilities · PostgreSQL 18.6
These are same-version documentary conclusions. Conditional capabilities depend on the operator class, indexed type or query; they are not universal guarantees.
| Capability | Support | Conditions and evidence |
|---|---|---|
| Sorted output | Yes | Ordinary sorted output is distinct from ordering by an operator, such as nearest-neighbor distance. Same-version documentation
|
| Unique keys | Yes | This means a unique index. Exclusion constraints use a different contract. Same-version documentation
|
| Multiple key columns | Yes | Multiple search keys are distinct from non-key INCLUDE payload columns. Same-version documentation
|
| INCLUDE columns | Yes | Payload columns do not become search keys. Wide payloads can exceed the index tuple-size limit. Same-version documentation
|
| Index-only scans | Yes | The query must use covered values; visibility-map state determines whether heap visits can be avoided. Same-version documentation
|
| Distance ordering | Not established | Availability depends on the chosen operator class and ordering operator. The sampled source does not establish this capability. This is not a “no”. |
| Parallel index scan | Yes | A cooperating scan of one index is distinct from a parallel bitmap heap scan or separate serial scans under Parallel Append. Same-version documentation
|
| Parallel index build | Yes | Parallel construction is separate from parallel scans. Worker availability, settings and build phases also matter. Same-version documentation
|
Queries, operators and limitations
CREATE INDEX name ON table_name USING btree (column_name);Syntax template; replace the table and column placeholders with suitable objects and choose a compatible operator class.
B-trees can handle equality and range queries on data that can be sorted into some ordering. In particular, the PostgreSQL query planner will consider using a B-tree index whenever an indexed column is involved in a comparison using one of these operators:
< <= = >= >Constructs equivalent to combinations of these operators, such as BETWEEN and IN , can also be implemented with a B-tree index search. Also, an IS NULL or IS NOT NULL condition on an index column can be used with a B-tree index.
The optimizer can also use a B-tree index for queries involving the pattern matching operators LIKE and ~ if the pattern is a constant and is anchored to the beginning of the string — for example, col LIKE 'foo%' or col ~ '^foo' , but not col LIKE '%bar' . However, if your database does not use the C locale you will need to create the index with a special operator class to support indexing of pattern-matching queries; see Section 11.10 below. It is also possible to use B-tree indexes for ILIKE and ~* , but only if the pattern starts with non-alphabetic characters, i.e., characters that are not affected by upper/lower case conversion.
B-tree indexes can also be used to retrieve data in sorted order. This is not always faster than a simple scan and sort, but it is often helpful.
Storage options
Set index options with CREATE INDEX … WITH or ALTER INDEX … SET. Defaults and effective behavior depend on the access method and selected PostgreSQL version.
fillfactor
Controls how full the index method will try to pack index pages. For B-trees, leaf pages are filled to this percentage during initial index builds, and also when extending the index at the right (adding new largest key values). If pages subsequently become completely full, they will be split, leading to fragmentation of the on-disk index structure. B-trees use a default fillfactor of 90, but any integer value from 10 to 100 can be selected.
B-tree indexes on tables where many inserts and/or updates are anticipated can benefit from lower fillfactor settings at CREATE INDEX time (following bulk loading into the table). Values in the range of 50 - 90 can usefully “ smooth out ” the rate of page splits during the early life of the B-tree index (lowering fillfactor like this may even lower the absolute number of page splits, though this effect is highly workload dependent). The B-tree bottom-up index deletion technique described in Section 65.1.4.2 is dependent on having some “ extra ” space on pages to store “ extra ” tuple versions, and so can be affected by fillfactor (though the effect is usually not significant).
In other specific cases it might be useful to increase fillfactor to 100 at CREATE INDEX time as a way of maximizing space utilization. You should only consider this when you are completely sure that the table is static (i.e. that it will never be affected by either inserts or updates). A fillfactor setting of 100 otherwise risks harming performance: even a few updates or inserts will cause a sudden flood of page splits.
The other index methods use fillfactor in different but roughly analogous ways; the default fillfactor varies between methods.
Same-version option definition
deduplicate_items
Controls usage of the B-tree deduplication technique described in Section 65.1.4.3 . Set to ON or OFF to enable or disable the optimization. (Alternative spellings of ON and OFF are allowed as described in Section 19.1 .) The default is ON .
Turning deduplicate_items off via ALTER INDEX prevents future insertions from triggering deduplication, but does not in itself make existing posting list tuples use the standard tuple representation.
Version comparison
No differences in documented capability states or storage-option inventory between these samples.
This comparison covers capability states and the names of documented storage options. It does not compare every algorithm, performance characteristic, option definition or release-note change.
Documented history
PostgreSQL 12 → 13
- Storage option recorded:
deduplicate_items - Storage option no longer recorded:
vacuum_cleanup_index_scale_factor
PostgreSQL 10 → 11
- INCLUDE columns: No → Yes
- Parallel index build: Not established → Yes (source coverage changed)
- Storage option recorded:
vacuum_cleanup_index_scale_factor
PostgreSQL 9.6 → 10
- Parallel index scan: Not established → Yes (source coverage changed)
PostgreSQL 9.5 → 9.6
- Index-only scans: Not established → Yes (source coverage changed)
Related documentation and objects
Sources and build identity
Extracted from the loaded English manual build 18.6. No runtime capability measurement is claimed.
- PostgreSQL 18.6: B-tree
- PostgreSQL 18.6 · catalog-pg-am
- PostgreSQL 18.6 · hash-index
- PostgreSQL 18.6 · indexam
- PostgreSQL 18.6 · indexes-index-only-scans
- PostgreSQL 18.6 · indexes-multicolumn
- PostgreSQL 18.6 · indexes-opclass
- PostgreSQL 18.6 · indexes-ordering
- PostgreSQL 18.6 · indexes-unique
- PostgreSQL 18.6 · parallel-plans
- PostgreSQL 18.6 · sql-createindex
Source fingerprints
- Manual build
- PostgreSQL 18.6 Documentation
- Combined page SHA-256
0e39ebd4fddbd990280e62f4503f0bd18765bbd990dccf4cba976b5d47da45e7- Source archive recorded by the manual manifest
- 18.6
- Archive SHA-256 recorded by the manual manifest
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f
- indexes-types.html:
cee340145a2ef5fbd807f66755b10d22bb049e328c460f572f45ad6193e7e4a1 - catalog-pg-am.html:
579364179365a51945e2edb6481df5d198916c2c725e506f166824dedf08994c - hash-index.html:
b994550220e1ee05648d09804c9eb2302834e07e261932420a96605d7c9c6140 - indexam.html:
0a38f7c0ac0541f31e086c83a624e782c15367456578a6dd3329882516bc1080 - indexes-index-only-scans.html:
2322ec12b82f3fd01ee4072049caaa5a0190148ac68d98c0fcd6eda958828a83 - indexes-multicolumn.html:
c0a799ec49b8ef057a63d465fb1d72a3b81e16d652c28a71734d45592d081202 - indexes-opclass.html:
07de06abf3a2aff2a891a2789def434d9b76705e54d45ca5338dc13451ae2962 - indexes-ordering.html:
85fac99c7c66ed19dd021f12b5cc53ce18aa5bfa4b56c8c168317f99b8f12d3b - indexes-unique.html:
7c3eac7fa180b22534ff01df0c68155f15b6b360ffe35507c5266059116840db - parallel-plans.html:
62207d207bead82b01b59dc119c4f95856f08655cc11d4699a05a40867ed2070 - sql-createindex.html:
6aa00da55815d13d0355dd25cb1cdb603fa36964993f164d1b6f486011282580
Back to Index AM · Recorded in PostgreSQL 9.0 through 20; first presence in this sample does not establish first introduction.