为啥 postgres 没有在我的查询中使用索引

Posted

技术标签:

【中文标题】为啥 postgres 没有在我的查询中使用索引【英文标题】:Why postgres is not using the index in my query为什么 postgres 没有在我的查询中使用索引 【发布时间】:2014-04-16 21:00:55 【问题描述】:

我有 2 个表如下:

tb_st:
Columns:
st_id  | integer
st     | character varying(80)
type   | integer
Indexes:
    PRIMARY KEY (st_id)
    UNIQUE INDEX (st, type)
    INDEX (st)

tb_pd:
Column
st_id  | integer
bot_id | integer
Indexes:
    PRIMARY KEY (st_id, bot_id)
    INDEX (bot_id)
Foreign-key constraints:
    FOREIGN KEY (st_id) REFERENCES tb_st(st_id)

当我解释查询时:

select p.bot_id
from tb_pd p inner join
     tb_st s
     on p.st_id = s.st_id
where s.st = 'abc' and s.type = 1

postgres 给了我这个:

 Nested Loop  (cost=4.24..16.10 rows=11 width=194)
   ->  Seq Scan on tb_st s  (cost=0.00..1.07 rows=1 width=186)
         Filter: (((st)::text = 'abc'::text) AND (type = 1))
   ->  Bitmap Heap Scan on tb_pd p  (cost=4.24..14.91 rows=11 width=8)
         Recheck Cond: (st_id = s.st_id)
         ->  Bitmap Index Scan on tb_pd_pkey  (cost=0.00..4.24 rows=11 width=0)
               Index Cond: (st_id = s.st_id)
(7 rows)

过了一会儿给了我这个完全相同的查询(仍然不使用索引):

 Nested Loop  (cost=0.00..2.19 rows=1 width=4)
   Join Filter: (p.st_id = s.st_id)
   ->  Seq Scan on tb_st s  (cost=0.00..1.07 rows=1 width=4)
         Filter: (((st)::text = 'abc'::text) AND (type = 1))
   ->  Seq Scan on tb_pd p  (cost=0.00..1.05 rows=5 width=8)
(5 rows)

我的问题是:如果我只通过一个 st 值和一个构成 UNIQUE INDEX 的类型值进行过滤,为什么不使用这个唯一索引?

【问题讨论】:

【参考方案1】:

您的表没有足够的行来使用索引。它们适合单个磁盘页面,因此使用 cpu 时间读取整个内容并过滤掉行比两次执行相同的操作(一次用于索引,另一次用于数据)更快。

【讨论】:

事情就是这样。我在表格中填充了数百万个用于测试的假行,并解释了所有内容的使用索引!我喜欢 postgres!

以上是关于为啥 postgres 没有在我的查询中使用索引的主要内容,如果未能解决你的问题,请参考以下文章

LIKE查询的最佳Postgres文本索引?

为啥在我的 Postgres 函数中使用 IF 语句时出现语法错误?

需要 POSTGRES 调优的建议

为啥我的 Apollo 缓存更新没有反映在我的查询中?

Postgres 上的索引

我的远程 Postgres 查询似乎永远挂起