PostgreSQL查询优化,阅读解释
我正在读取对查询运行解释的输出。结果是: 我看到在第34行,DB正在做一个非常昂贵的索引扫描,结果删除了一行 我读对了吗?还有,是什么原因造成的 查询:PostgreSQL查询优化,阅读解释,postgresql,sql-execution-plan,Postgresql,Sql Execution Plan,我正在读取对查询运行解释的输出。结果是: 我看到在第34行,DB正在做一个非常昂贵的索引扫描,结果删除了一行 我读对了吗?还有,是什么原因造成的 查询: explain analyze select *, posts.type as type, posts.created as created, posts.image_url as image_url, posts.id as post_id, posts.organization_id as id, urls.image_url as
explain analyze select *, posts.type as type, posts.created as created, posts.image_url as image_url, posts.id as post_id, posts.organization_id as id,
urls.image_url as url_image_url,
ts_headline('english',posts.text , to_tsquery('english', 'state') , $$StartSel='<span class="text-highlight">',StopSel=</span>, HighlightAll=true$$) as text,
ts_headline('english',posts.attachment_description, to_tsquery('english', 'state') , $$StartSel='<span class="text-highlight">',StopSel=</span>, HighlightAll=true$$) as attachment_description,
ts_headline('english',posts.attachment_title, to_tsquery('english', 'state') , $$StartSel='<span class="text-highlight">',StopSel=</span>, HighlightAll=true$$) as attachment_title
from vision2.posts15 as posts join vision2.organizations on organizations.id=posts.organization_id left join vision2.urls on urls.id = posts.url_id where chunks @@ to_tsquery('english', 'state') and string_to_array(upper(organizations.irs_state), '') && array['NJ'] and Date(posts.created) >= '2017-08-10' and Date(posts.created) <= '2017-08-24' and Date(posts.partition_date) >= '2017-08-10' and Date(posts.partition_date) <= '2017-08-24' order by posts.created desc offset 0 limit 40
尝试在执行联接之前限制数据。您可以使用CTE,因为它们只被物化一次,并且可以像优化围栏或临时表一样工作 因此,您的查询可能如下所示:
WITH cte_posts AS (
select type, created, image_url, id as post_id, organization_id as id, url_id,
ts_headline('english',
text,
to_tsquery('english', 'state'),
$$StartSel='<span class="text-highlight">',StopSel=</span>, HighlightAll=true$$) as text,
ts_headline('english',
attachment_description,
to_tsquery('english', 'state'),
$$StartSel='<span class="text-highlight">',StopSel=</span>, HighlightAll=true$$) as attachment_description,
ts_headline('english',
attachment_title,
to_tsquery('english', 'state'),
$$StartSel='<span class="text-highlight">',StopSel=</span>, HighlightAll=true$$) as attachment_title
from vision2.posts15
where Date(created) BETWEEN '2017-08-10' AND '2017-08-24'
and Date(partition_date) BETWEEN '2017-08-10' AND '2017-08-24'
AND chunks @@ to_tsquery('english', 'state') --is that column in posts15 table?
)
SELECT cte_posts.*, urls.image_url as url_image_url
FROM cte_posts
join vision2.organizations on organizations.id = cte_posts.id
left join vision2.urls on urls.id = cte_posts.url_id
--you could try moving this WHERE to CTE as well, depending on your data
where string_to_array(upper(organizations.irs_state), '') && array['NJ']
order by cte_posts.created desc
offset 0
limit 40
请注意,该表中的单个行是廉价的0.013ms,但该表上有870k个循环。您是否尝试过在您创建的日期和/或块上创建索引?请注意,在计划的上面几层上,行大小相当大~1K。散列表可能会溢出到磁盘。顺便说一句:请将您的查询编辑为可读的内容……您能再次检查您发布的查询是否与执行计划一致吗?有些东西不匹配,例如,执行计划中没有分区\日期筛选器,但它们在where子句中,执行计划中的解析器正在查找educ,而查询显示“英语”、“状态”。无论如何,我的直觉是,查询并没有绑定到SELECT4执行计划。执行计划实际上看起来可能在posts表上存在两次恶意连接。