为什么创建不相关的索引会使我的查询更快?
Why does creating an unrelated index make my query faster?
我有一个 table:
debts (
name text,
inv_no integer,
inv_type text,
status text,
);
我有一个关注 select:
SELECT COUNT(*) FROM debts WHERE name = '...' AND inv_no = 100 AND inv_type = '...';
为了优化其他内容,我添加了:
CREATE INDEX ON debt (status);
我在 SELECT 中没有提到状态,但是 运行...
EXPLAIN SELECT COUNT(*)... (as above)
...在创建索引之前和之后,我将成本 16.65..16.66 更改为 1.25..1.26。为什么?
完整 explain (analyze, verbose)
before/after:
之前:
QUERY PLAN
----------
Aggregate (cost=16.65..16.66 rows=1 width=0) (actual time=0.126..0.128 rows=1 loops=1)
Output: count(*)
-> Seq Scan on ab123456.debts (cost=0.00..16.65 rows=1 width=0) (actual time=0.106..0.106 rows=0 loops=1)
Output: name, inv_no, inv_type, status
Filter: ((debts.name = '...'::text) AND (debts.inv_type = '...'::text) AND (debts.inv_no = 100))
Total runtime: 0.387 ms
之后:
QUERY PLAN
----------
Aggregate (cost=1.25..1.26 rows=1 width=0) (actual time=0.031..0.033 rows=1 loops=1)
Output: count(*)
-> Seq Scan on ab123456.debts (cost=0.00..1.25 rows=1 width=0) (actual time=0.024..0.024 rows=0 loops=1)
Output: name, inv_no, inv_type, status
Filter: ((debts.name = '...'::text) AND (debts.inv_type = '...'::text) AND (debts.inv_no = 100))
Total runtime: 0.118 ms
一些实用程序语句(包括 CREATE INDEX
!)在执行时会更新 table 统计信息。 The manual:
For efficiency reasons, reltuples
and relpages
are not updated
on-the-fly, and so they usually contain somewhat out-of-date values.
They are updated by VACUUM
, ANALYZE
, and a few DDL commands such as CREATE INDEX
.
大胆强调我的。因此,即使您的索引看起来完全不相关,更新后的 table 统计数据也会产生影响 - 特别是 count()
,这主要取决于所提到的两个统计数据。
相关:
我有一个 table:
debts (
name text,
inv_no integer,
inv_type text,
status text,
);
我有一个关注 select:
SELECT COUNT(*) FROM debts WHERE name = '...' AND inv_no = 100 AND inv_type = '...';
为了优化其他内容,我添加了:
CREATE INDEX ON debt (status);
我在 SELECT 中没有提到状态,但是 运行...
EXPLAIN SELECT COUNT(*)... (as above)
...在创建索引之前和之后,我将成本 16.65..16.66 更改为 1.25..1.26。为什么?
完整 explain (analyze, verbose)
before/after:
之前:
QUERY PLAN
----------
Aggregate (cost=16.65..16.66 rows=1 width=0) (actual time=0.126..0.128 rows=1 loops=1)
Output: count(*)
-> Seq Scan on ab123456.debts (cost=0.00..16.65 rows=1 width=0) (actual time=0.106..0.106 rows=0 loops=1)
Output: name, inv_no, inv_type, status
Filter: ((debts.name = '...'::text) AND (debts.inv_type = '...'::text) AND (debts.inv_no = 100))
Total runtime: 0.387 ms
之后:
QUERY PLAN
----------
Aggregate (cost=1.25..1.26 rows=1 width=0) (actual time=0.031..0.033 rows=1 loops=1)
Output: count(*)
-> Seq Scan on ab123456.debts (cost=0.00..1.25 rows=1 width=0) (actual time=0.024..0.024 rows=0 loops=1)
Output: name, inv_no, inv_type, status
Filter: ((debts.name = '...'::text) AND (debts.inv_type = '...'::text) AND (debts.inv_no = 100))
Total runtime: 0.118 ms
一些实用程序语句(包括 CREATE INDEX
!)在执行时会更新 table 统计信息。 The manual:
For efficiency reasons,
reltuples
andrelpages
are not updated on-the-fly, and so they usually contain somewhat out-of-date values. They are updated byVACUUM
,ANALYZE
, and a few DDL commands such asCREATE INDEX
.
大胆强调我的。因此,即使您的索引看起来完全不相关,更新后的 table 统计数据也会产生影响 - 特别是 count()
,这主要取决于所提到的两个统计数据。
相关: