pingcap / pingcap/tidb

Planner: Suboptimal plan choices for multiple indexes with order requirement

Open
#66,297 0 comments 0 reactions 1 assignee Claimed by @terry1purcell View on GitHub
type/enhancement
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Enhancement

Given the following simple query - there is no supporting index (see DDL) that provides filtering on the WHERE clause, and also provides order. The optimizer may choose one of 3 logical options:
1. Table full scan - apply filter and sort/TopN.
2. Index scan on ic(c) - sort/TopN.
3. Use index ib(b) to provide order, and LIMIT - but filtering must be applied on table rows.
None of the above may be optimal. And it is not always possible to create a multi-column index - especially when dealing with more flexible queries where filters or ordering may encompass a large number of combinations. In these instances - many single columns indexes are common for simplicity in table/index design.
```
Explain select *
From t1
Where c = 5
Order by b
Limit 10;

Explain analyze select *
From t1 use index(ib)
Where c = 5
Order by b
Limit 10;
```
DDL & INSERTs to reproduce:
```
CREATE TABLE `t1` (
`a` int,
`b` int,
`c` int,
Primary KEY `ia` (`a`),
KEY `ib` (`b`),
KEY `ic` (`c`)
);

set @@cte_max_recursion_depth=10000000;
INSERT INTO t1 (a, b, c)
SELECT a,
mod(a, 100) AS b,
CASE WHEN a BETWEEN 500000 AND 510000 THEN 5
ELSE mod(a, 4) -- produces 0,1,2,3 only — never 5
END AS c
FROM (
WITH RECURSIVE x AS (
SELECT 1 AS a
UNION ALL
SELECT a + 1 FROM x WHERE a < 1000000
)
SELECT a FROM x
) AS subquery;
ANALYZE TABLE t1;
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.