鉴于:
postgres=# \d b
Table "public.b"
Column | Type | Collation | Nullable | Default
--------+------+-----------+----------+---------
a | uuid | | not null |
Indexes:
"b_a_idx" btree (a)
postgres=# \d c
Table "public.c"
Column | Type | Collation | Nullable | Default
--------+------+-----------+----------+---------
a | text | | not null |
Indexes:
"c_a_idx" btree (a)
postgres=# explain b;
ERROR: syntax error at or near "b"
LINE 1: explain b;
^
postgres=# analyze b;
ANALYZE
postgres=# analyze c;
ANALYZE
为什么下面的查询不使用b.a
's 索引?
postgres=# explain (select * from b join c on (b.a :: text) = c.a);
QUERY PLAN
---------------------------------------------------------------------------------
Merge Join (cost=129.05..455.25 rows=12580 width=48)
Merge Cond: (c.a = ((b.a)::text))
-> Index Only Scan using c_a_idx on c (cost=0.15..64.55 rows=1360 width=32)
-> Sort (cost=128.89..133.52 rows=1850 width=16)
Sort Key: ((b.a)::text)
-> Seq Scan on b (cost=0.00..28.50 rows=1850 width=16)
(6 rows)
因为索引只存储 的 UUID 值
a
,而不是表达式的结果a::text
要使索引符合使用条件,您需要将另一列转换为存储在索引中的数据类型,例如
请注意,这并不能保证使用索引,它只是使其成为可能。
但是当查询从两个表中检索所有行时,无论如何都不太可能使用索引。