Я создал индекс как
CREATE INDEX bill_open_date_idx ON bill USING btree(date(open_date));
и,
Column | Type
open_date | timestamp without time zone
И объяснить, проанализировать так
ДЕЛО 1
explain analyze select * from bill where open_date >=date('2018-01-01');
Seq Scan on bill (cost=0.00..345264.60 rows=24813 width=1132) (actual time=0.007..1305.730 rows=5908 loops=1)
Filter: (open_date >= '2018-01-01'::date)
Rows Removed by Filter: 3238812
Total runtime: 1306.176 ms
СЛУЧАЙ 2
explain analyze select * from bill where open_date>='2018-01-01';
Seq Scan on bill (cost=0.00..345264.60 rows=24813 width=1132) (actual time=0.006..1220.697 rows=5908 loops=1)
Filter: (open_date>= '2018-01-01 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 3238812
Total runtime: 1221.131 ms
СЛУЧАЙ 3
explain analyze select * from bill where date(open_date) >='2018-01-01';
Index Scan using idx_bill_open_date on bill (cost=0.43..11063.18 rows=22747 width=1132) (actual time=0.016..4.744 rows=5908 loops=1)
Index Cond: (date(open_date) >= '2018-01-01'::date)
Total runtime: 5.236 ms
(3 rows)
Я достаточно исследовал, почему это происходит, но нигде нет правильных объяснений. Только case 3 использует созданный мной индекс, но не другие. Почему это происходит?
Насколько я понимаю, case 2 ищет строковый эквивалент столбца open_date
и, следовательно, не использует индекс. Но почему нет случая 1. Также, пожалуйста, поправьте меня, если я ошибаюсь.
Заранее спасибо!
Edit 1: Кроме того, я был бы рад узнать, что происходит в глубине.
Ниже приводится выдержка из сущности (https://gist.github.com/cobusc/5875282)
Странно, однако, что PostgreSQL переписывает функцию, используемую для
создать индекс в каноническую форму, но, похоже, не делает то же самое
когда функция используется в предложении WHERE (чтобы соответствовать
индексная функция).
Тем не менее, мне неясно, почему разработчики postgres не думали о получении какого-либо близлежащего совпадающего индекса (или мой индекс бесполезен, пока я не приведу явно к date
, как в case 3 ). Учитывая, что Postgres высоко развит и масштабируем.