Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad index plan for lookup on multiple columns. #8884

Open
nicktobey opened this issue Feb 23, 2025 · 0 comments
Open

Bad index plan for lookup on multiple columns. #8884

nicktobey opened this issue Feb 23, 2025 · 0 comments
Labels

Comments

@nicktobey
Copy link
Contributor

Repro steps:

create table test(pk int primary key, c0 int, key idx1(c0, pk));
insert into test values (1, 0), (2, 1), (3, 2), (4, 1), (5, 2), (6, 0), (7, 2), (8, 0), (9, 1);
describe plan select * from test where c0 = 1 and pk > 1;
alter table test add key idx2(c0);
describe plan select * from test where c0 = 1 and pk > 1;

The first describe shows the correct, optimal plan: an IndexedTableAccess doing a lookup on both columns.

+---------------------------------------+
| plan                                  |
+---------------------------------------+
| Filter                                |
|  ├─ ((test.c0 = 1) AND (test.pk > 1)) |
|  └─ IndexedTableAccess(test)          |
|      ├─ index: [test.c0,test.pk]      |
|      ├─ filters: [{[1, 1], (1, ∞)}]   |
|      └─ columns: [pk c0]              |
+---------------------------------------+

However, the second describe produces a suboptimal plan:

+---------------------------------------+
| plan |
+---------------------------------------+
| Filter |
| ├─ ((test.c0 = 1) AND (test.pk > 1)) |
| └─ IndexedTableAccess(test) |
| ├─ index: [test.c0] |
| ├─ filters: [{[1, 1]}] |
| └─ columns: [pk c0] |
+---------------------------------------+

There are two things wrong here:

  1. The two indexes are identical. Literally. They have the exact same tree hash. This is because non-unique index keys append the primary key to the end in order to make them unique in the underlying map. Thus, although one index is declared as (c0) and the other is declared as (c0, pk), they contain the exact same data and can optimize the exact same queries. Choosing idx2 should not result in a worse plan.

  2. Assuming that the engine doesn't know that the indexes are identical (and doesn't realize that idx2 can be used to lookup both columns), it still shouldn't be choosing idx2 for this query. It should deduce that idx1 produces a better plan and choose that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant