Я не знаю причину, но выяснилось, что это произошло, когда было выполнено сканирование только по индексу на реплике чтения Aurora Postgres.
Я посмотрел каждый план выполнения, и он выглядел следующим образомэто. Для столбца даты используется индекс.
SELECT *
testdb=> explain analyse select * from samples where date between '2019-09-25 00:00:00' and '2019-09-26 00:00:00';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using idx_samples on samples (cost=0.43..5852.48 rows=3906 width=627) (actual time=0.014..18.325 rows=17613 loops=1)
Index Cond: ((date >= '2019-09-25'::date) AND (date <= '2019-09-26'::date))
Planning time: 1.154 ms
Execution time: 18.969 ms
(4 rows)
В этом случае для получения данных в виде записи выбирается не только индекс, но и фактические данные. В результате этого могут быть возвращены 17613 строк.
SELECT COUNT(*)
testdb=> explain analyse select count(*) from samples where date between '2019-09-25 00:00:00' and '2019-09-26 00:00:00';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=200.32..200.33 rows=1 width=8) (actual time=19.971..19.972 rows=1 loops=1)
-> Index Only Scan using idx_samples on samples (cost=0.43..190.56 rows=3906 width=0) (actual time=0.022..18.901 rows=17875 loops=1)
Index Cond: ((date >= '2019-09-25'::date) AND (date <= '2019-09-26'::date))
Heap Fetches: 59983
Planning time: 1.125 ms
Execution time: 19.994 ms
(6 rows)
Однако если при подсчете получено только количество записей, столбец даты, добавленный в условие, является целью индекса, поэтому Index Only Scan
используется. В результате 17875 строк имеют право на возврат.
Это не происходит с мастерами Aurora, только с репликами чтения.
Я много искал и не могу найтистатья о первопричине возникновения ненужных кортежей или о том, что вакуум не сделан. Я также искал форумы Aurora и Postgresql, но не смог найти такую статью. Инженер, работающий со мной над этим событием, не мог скрыть удивления.
Я думаю, что количество фактических данных - это правильный ответ, а не результат сканирования только по индексу. Как решение, я собираюсьпроверить количество столбцов, которые не проиндексированы счетчиком, например SELECT COUNT (sample_id)
.
Было бы полезно, если бы кто-то поделился статьей о причине этого события или о том, что это была такая спецификация.