Sql 当where子句只包含索引的第一列时,为什么不使用索引?

Sql 当where子句只包含索引的第一列时,为什么不使用索引?,sql,postgresql,Sql,Postgresql,以下是select语句: SELECT COUNT(*) FROM object_detection_label where company_id = 'SOME_COMPANY_ID' 行数:4700万 表列:id、公司id、职务id、航班计划id、媒体id、顶部、左侧、底部、右侧、置信等级id、等级版本、显示id 主键:id 索引:公司id、工作id、航班计划id、媒体id 结果来源:EXPLAIN ANALYZE SELECT*from object_detection_label,其中

以下是select语句:

SELECT COUNT(*) FROM object_detection_label where company_id = 'SOME_COMPANY_ID'
行数:4700万

表列:id、公司id、职务id、航班计划id、媒体id、顶部、左侧、底部、右侧、置信等级id、等级版本、显示id

主键:id

索引:公司id、工作id、航班计划id、媒体id

结果来源:EXPLAIN ANALYZE SELECT*from object_detection_label,其中company_id=‘SOME_company_id’

结果来源:EXPLAIN Analysis SELECT*from object_detection_label,其中company_id='SOME_company_id'和job_id='SOME_job_id'

注意,如果我将job_id作为where子句的一部分,它将使用位图热扫描而不是索引扫描

在将索引添加到公司id之后,它仍然没有使用索引扫描。为什么会这样?如何使用索引扫描?

位图索引扫描是一种索引扫描

结果集是47000000行中的600000行,它们位于14000个块中

这意味着,使用正常的索引扫描,每个块都必须访问几次,这是低效的。位图索引扫描按顺序获取所需的表块,每个块仅获取一次。PostgreSQL估计这会更有效,而且可能是正确的

您可以通过在设置后重新运行查询来验证这一点

SET enable_bitmapscan = off;

注:为什么有文本键域?表列:id、公司id、工作id、航班计划id、媒体id、顶部、左侧、底部、右侧、信心等级id、等级版本、显示id。我担心的是:这里有数据建模问题……公司id的基数是什么?@jmelesky:没错!以及所有其他xxx_id列
"Index Scan using company_id_job_id_fp_id_media_id_idx on object_detection_label  (cost=0.69..418.71 rows=102 width=153) (actual time=0.064..6.912 rows=13206 loops=1)"
"  Index Cond: (((company_id)::text = 'CHURCH_OF_JESUS_CHRIST'::text) AND ((job_id)::text = '5cc085baa635404e54ebd46e'::text))"
"Planning time: 0.110 ms"
"Execution time: 10.114 ms"
SET enable_bitmapscan = off;