[YSQL] Index cost estimates should account for index and scan type
m-iancu opened this issue · 1 comments
m-iancu commented
Among other things, when evaluating the per-row and index cost we should consider:
- Index uniqueness (e.g. fully-specified key guarantee single-row results for unique indexes, but not for non-unique indexes).
- Included columns (i.e.
Index Scan
vsIndex Only Scan
). Index scans will require an additional read from the main table to retrieve the needed columns (these are batched so costs are somewhat amortized). - Scan direction -- in DocDB reverse scans are (somewhat) slower than forward scans, so we should prefer fwd scans if all else is equal.
- Partial indexes -- the partial index predicate will mean the index size (number of rows) will be less than the table (depending on how restrictive the predicate is). The cost estimate should account for the predicate filter in addition to the index condition filter.
Example:
CREATE TABLE test(device_id int primary key, device_name text UNIQUE, supplier_id int);
CREATE INDEX ON test(supplier_id);
INSERT INTO test (SELECT generate_series, generate_series::text, 1 FROM generate_series(1, 100000));
EXPLAIN ANALYZE SELECT * FROM test WHERE device_name = '1' AND supplier_id = 1;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
Index Scan using test_supplier_id_idx on test (cost=0.00..4.12 rows=1 width=40) (actual time=82.820..842.473 rows=1 loops=1)
Index Cond: (supplier_id = 1)
Filter: (device_name = '1'::text)
Rows Removed by Filter: 99999
Planning Time: 0.116 ms
Execution Time: 842.639 ms
(6 rows)
Query takes ~850ms
, even though it could be executed as a single-key read if using the right index (on device_name
, not supplier_id
).