暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL for MySQL DBA第6集-解释和解释(以及对额外问题的回答)

原创 eternity 2022-08-10
317

MySQL和PostgreSQL之间的差异通常微不足道,但偶尔也会有明显的差异。希望在PostgreSQL服务器上优化查询的MySQL DBA将有一些使用EXPLAIN的经验。对于未初始化的用户,关键字EXPLAIN将预先挂起到查询中,以显示服务器想要执行哪些操作来返回该查询中请求的数据。解释的两个版本的实现非常不同。PostgreSQL for MySQL DBA系列的第六集包括解释。

那么有什么不同呢? PostgreSQL添加了XML和YAML输出格式选项,超越了MySQL中的传统和JSON。至少在我看来,PostgreSQL的输出看起来像MySQL的树输出。但由于这两个数据库“机械”不同,您需要学习如何解释PostgreSQL提供的输出。

下面的示例提供了详细信息,例如服务器获取数据的机制、启动成本、总体成本、要返回的行数以及使用的键的名称(如果有)。有关详细信息,请参阅视频。

test=# EXPLAIN SELECT 1 FROM t1 WHERE ID=101;
QUERY PLAN
-----------------------------------------------------------------------
Index Only Scan using t1_pkey on t1 (cost=0.29..4.31 rows=1 width=4)
Index Cond: (id = 101)
(2 rows)
复制

请参阅视频以了解差异,并快速介绍PostgreSQL的解释。

测验答案

我在演示文稿和视频中添加了一个“奖励问答题”。
微信图片_20220808100826.png
视频中的奖励问答题

第一个做出回应的人是杰克·T:

您之前说过,“序列扫描”是全表扫描,仅执行该扫描需要15.54毫秒。理论上,如果在postal_ code上添加索引,则这将变为“索引扫描”,执行时间将减少。在MySQL中,该子查询模式被识别为“半连接”,并作为连接执行。PGSQL是否有类似的重写优化?

这就是使用一个数据库的经验可以帮助您掌握另一个数据库。通常,添加索引将加快查询速度。但要了解PostgreSQL,需要记住的一件大事是,它有不同的处理方式。

让我们重新运行EXPLAIN,谢天谢地,这些数字与我的测试机匹配。

dvdrental=# EXPLAIN SELECT * FROM customer WHERE address_id IN (SELECT address_id FROM address WHERE postal_code = '52137');
QUERY PLAN
-----------------------------------------------------------------------------------------
Nested Loop (cost=0.28..32.14 rows=2 width=70)
-> Seq Scan on address (cost=0.00..15.54 rows=2 width=4)
Filter: ((postal_code)::text = '52137'::text)
-> Index Scan using idx_fk_address_id on customer (cost=0.28..8.29 rows=1 width=70)
Index Cond: (address_id = address.address_id)

<span style="font-size: 10px;">(5 rows)</span>
复制

然后我们可以在postal_code列中创建索引。

dvdrental=# CREATE INDEX quiz_answer_1 ON address (postal_code);
CREATE INDEX
复制

因此,我们重新运行EXPLAIN并查看结果。

dvdrental=# EXPLAIN SELECT * FROM customer WHERE address_id IN (SELECT address_id FROM address WHERE postal_code = '52137');
QUERY PLAN
-----------------------------------------------------------------------------------------
Nested Loop (cost=4.57..25.92 rows=2 width=70)
-> Bitmap Heap Scan on address (cost=4.29..9.32 rows=2 width=4)
Recheck Cond: ((postal_code)::text = '52137'::text)
-> Bitmap Index Scan on quiz_answer_1 (cost=0.00..4.29 rows=2 width=0)
Index Cond: ((postal_code)::text = '52137'::text)
-> Index Scan using idx_fk_address_id on customer (cost=0.28..8.29 rows=1 width=70)
Index Cond: (address_id = address.address_id)
 
(7 rows)
复制

结果很有趣。请注意,idx_fx_address_id的索引扫描成本保持不变,因为新索引在客户表上不起作用,但新索引确实将地址扫描从15.54降到了9.32。嵌套外观成本从32.14降到了25.92。优化是位图扫描。

根据PostgreSQL手册,规划人员决定使用两步计划:底部计划节点访问索引以查找与索引条件匹配的行的位置,然后上部计划节点实际从表本身获取这些行。单独获取行比顺序读取行要昂贵得多,但由于不必访问表中的所有页面,因此这仍然比顺序扫描便宜。(使用两级计划的原因是,上层计划节点在读取索引之前将索引标识的行位置按物理顺序排序,以最小化单独提取的成本。节点名称中提到的“位图”是进行排序的机制。)

因此,索引确实加快了查询速度,但优化的方式与MySQL使用的方式大不相同。

下一集—真空清理表

敬请期待!

PostgreSQL for MySQL数据库管理员(DBA)过去的视频可以在这里找到:第一集、第二集、第三集、第四集和第五集。

作者

David Stokes是Percona公司的技术传道者,是MySQL和JSON的作者-实用编程指南,居住在德克萨斯州。

原文标题:PostgreSQL for MySQL DBAs Episode 6 – Explaining EXPLAIN (And an Answer to a Bonus Question)
原文作者:David Stokes
原文链接:https://www.percona.com/blog/postgresql-for-mysql-dbas-episode-6-explaining-explain-and-an-answer-to-a-bonus-question/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论