Eu tenho a tabela customers
tendo customerid SERIAL
como chave primária. Inicialmente, eu tinha a seguinte estatística para essa coluna:
attname n_distinct correlation
customerid -1 -0.393365
A seguinte consulta
EXPLAIN ANALYZE SELECT * FROM customers WHERE customerid < 10
produziu o seguinte plano analisado:
Index Scan using customers_pkey on customers (cost=0.00..35.46 rows=9 width=268) (actual time=0.003..0.010 rows=9 loops=1)
Index Cond: (customerid < 10)
Total runtime: 0.029 ms
Observe que o custo para obter todas as linhas é 35.46
. Agora eu corri
CLUSTER customers USING customers_pkey;
ANALYZE;
e o correlation
tornou-se igual a 1
. Depois de executar a consulta mais uma vez, obtive o seguinte plano analisado:
Index Scan using customers_pkey on customers (cost=0.00..8.41 rows=9 width=268) (actual time=0.003..0.005 rows=9 loops=1)
Index Cond: (customerid < 10)
Total runtime: 0.024 ms
Observe que o custo diminuiu mais de 4 vezes ( 8.41
agora). Minha pergunta é como exatamente o custo ranged index scan
depende da correlação? Como é computado? Seria bom se você indicasse algumas referências à documentação do postgresql.
Os detalhes que você deseja não serão encontrados na documentação, mas sim no código-fonte. Em particular,
src/backend/optimizer/path/costsize.c
na funçãocost_index
.Ele calcula
min_IO_cost
com base na suposição de que a tabela está correlacionada,max_IO_cost
com base na suposição de que não está correlacionada e, em seguida, interpola entre elas com base na correlação.