Postgresql Postgres执行计划where条款的命令和命令依据
我有一个非常简单的SQL:Postgresql Postgres执行计划where条款的命令和命令依据,postgresql,sql-execution-plan,Postgresql,Sql Execution Plan,我有一个非常简单的SQL: select * from email.email_task where acquire_time < now() and state IN ('CREATED', 'RELEASED') order by creation_time asc limit 1; 从email.email\u任务中选择*,其中获取时间排序(成本=187404.36..190753.58行=1339690宽度=743) 排序键:创建时间 ->电子邮件任务上的顺序扫描(成本=0.00
select * from email.email_task where acquire_time < now() and state IN ('CREATED', 'RELEASED') order by creation_time asc limit 1;
从email.email\u任务中选择*,其中获取时间
我创建了两个索引:
Limit (cost=187404.36..187404.36 rows=1 width=743)
-> Sort (cost=187404.36..190753.58 rows=1339690 width=743)
Sort Key: creation_time
-> Seq Scan on email_task (cost=0.00..180705.91 rows=1339690 width=743)
Filter: (((state)::text = 'CREATED'::text) AND (acquire_time < now()))
限制(成本=187404.36..187404.36行=1宽=743)
->排序(成本=187404.36..190753.58行=1339690宽度=743)
排序键:创建时间
->电子邮件任务上的顺序扫描(成本=0.00..180705.91行=1339690宽度=743)
筛选器:((状态)::text='CREATED'::text)和(acquire_time
我知道,如果返回的行数达到总数的10%,那么它将选择Seq扫描而不是索引扫描。(详情请参阅
)这就是为什么不选择index1
我不明白的是,既然index2匹配所有列,为什么不选择index2
然后我尝试了第三个索引:
限制(成本=0.29..0.36行=1宽度=75)(实际时间=0.043..0.043行=1圈=1)
->在电子邮件任务上使用性能1进行索引扫描(成本=0.29..763.76行=9998宽度=75)(实际时间=0.042..0.042行=1循环=1)
索引条件:(获取时间<现在()
筛选器:((状态)::text=ANY(“{CREATED,RELEASED}”::text[]))
似乎Postgres execution planner首先选择order by子句,然后选择where子句,这有点违反直觉
我的理解正确吗?或者还有其他一些因素会影响博士后计划员
提前感谢。最后一个使用
acquire\u time
索引的查询计划与您声称的索引完全不同。此外,该计划不包含排序条件,因此对于该计划,未使用排序依据。也就是说,第三个查询计划与您提供的查询无关。对于未使用的第二个索引,是因为其中两列位于WHERE中,1列按顺序排列,因此您有一个索引。为了在所有条件下启动第二个索引,必须在相同的“级别”上存在。意思是,例如,所有3列都在WHERE.Hi@KristoMägi。感谢您的评论,第三个查询计划使用了“perf_1”索引,即(创建时间、获取时间、状态)。获取时间实际上是列名。我确认SQL中使用了Order By:explain analyze select*from email.email\u任务,其中获取时间
使用索引acquire\u time
的最后一个查询计划中说明您所做的索引。此外,该计划不包含排序条件,因此对于该计划,未使用排序依据。也就是说,第三个查询计划与您提供的查询无关。对于未使用的第二个索引,是因为其中两列位于WHERE中,1列按顺序排列,因此您有一个索引。为了在所有条件下启动第二个索引,必须在相同的“级别”上存在。意思是,例如,所有3列都在WHERE.Hi@KristoMägi。感谢您的评论,第三个查询计划使用了“perf_1”索引,即(创建时间、获取时间、状态)。获取时间实际上是列名。我确认在SQL中使用了Order By:explain analyze select*from email.email\u任务,其中获取时间Limit (cost=0.29..0.36 rows=1 width=75) (actual time=0.043..0.043 rows=1 loops=1)
-> Index Scan using perf_1 on email_task (cost=0.29..763.76 rows=9998 width=75) (actual time=0.042..0.042 rows=1 loops=1)
Index Cond: (acquire_time < now())
Filter: ((state)::text = ANY ('{CREATED,RELEASED}'::text[]))