我有一个表格的查询:
select m.id from mytable m
left outer join othertable o on o.m_id = m.id
and o.col1 is not null and o.col2 is not null and o.col3 is not null
where o.id is null
Run Code Online (Sandbox Code Playgroud)
该查询返回几百条记录,尽管这些表有数百万行,并且需要永久运行(大约一小时).
使用以下方法检查索引统计信息时:
select * from pg_stat_all_indexes
where schemaname <> 'pg_catalog' and (indexrelname like 'othertable_%' or indexrelname like 'mytable_%')
Run Code Online (Sandbox Code Playgroud)
我看到只使用了othertable.m_id的索引,并且根本没有使用col1..3的索引.为什么是这样?
我在一些 地方读过PG传统上无法索引NULL值.但是,据我所知,自从PG 8.3以来这已经发生了变化?我目前正在Ubuntu 10.04上使用PostgreSQL 8.4.我是否需要专门制作一个"部分"或"功能"索引来加速IS NOT NULL查询,或者它是否已经将NULL编入索引并且我只是误解了这个问题?
我有一个简单的查询来连接两个非常慢的表.我发现查询计划在大表email_activities(~10m行)上执行seq扫描,而我认为使用嵌套循环的索引实际上会更快.
我使用子查询重写了查询,试图强制使用索引,然后注意到一些有趣的东西.如果您查看下面的两个查询计划,您将看到当我将子查询的结果集限制为43k时,查询计划确实使用了email_activities上的索引,而将子查询中的限制设置为甚至44k将导致查询计划使用seq扫描email_activities.一个显然比另一个更有效,但Postgres似乎并不关心.
什么可能导致这个?如果其中一个集合大于特定大小,它是否在某处强制使用散列连接?
explain analyze SELECT COUNT(DISTINCT "email_activities"."email_recipient_id") FROM "email_activities" where email_recipient_id in (select "email_recipients"."id" from email_recipients WHERE "email_recipients"."email_campaign_id" = 1607 limit 43000);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=118261.50..118261.50 rows=1 width=4) (actual time=224.556..224.556 rows=1 loops=1)
-> Nested Loop (cost=3699.03..118147.99 rows=227007 width=4) (actual time=32.586..209.076 rows=40789 loops=1)
-> HashAggregate (cost=3698.94..3827.94 rows=43000 width=4) (actual time=32.572..47.276 rows=43000 loops=1)
-> Limit (cost=0.09..3548.44 rows=43000 width=4) (actual time=0.017..22.547 rows=43000 loops=1)
-> Index Scan using index_email_recipients_on_email_campaign_id on email_recipients (cost=0.09..5422.47 rows=65710 width=4) (actual time=0.017..19.168 rows=43000 loops=1) …Run Code Online (Sandbox Code Playgroud)