随笔,PostgreSQL面试准备篇。

112 阅读5分钟

索引失效的原因?

  • hash index不支持范围查询
  • 列与索引字符集(或排序规则)不一致(例如表关联字段)
  • 隐式转换
  • 软解析使用缓存的全表扫描执行计划,后续默认不会再解析生成新执行计划。
  • 非SARG条件:
    • 字段上用函数,immutable类型函数可以建函数索引
    • 字段上做运算
    • 非操作符条件,not in,<>,!=,not like
    • like左边带%(使用pg_trgm插件创建gin索引除外)

函数的三个状态?以及函数为什么要有execute?

函数三态

volatile(不稳定,默认)
  • 可以做任何事,包括修改数据库。
  • 在同一个事务中,即使是相同的参数,返回的结果也会不同。在函数内的每个query开始时获取snapshot,因此在函数执行过程中,外部已提交的数据可见。
  • 由于每次要重新计算,优化器无法提前预估,其性能可能较差。
  • 不支持创建函数索引。
  • 典型函数:timeofday()、random()、所有修改类函数。
stable(稳定)
  • 不可以修改数据库。
  • 在同一个事务中,对于相同的参数,返回的结果相同。在函数开始执行时获取snapshot,内部的每个query不再重复获取,因此在函数执行过程中,外部已提交的数据不可见。
  • 不支持创建函数索引
  • 典型函数:current_timestamp()。
immutable(非常稳定)
  • 不可以修改数据库。
  • 只要给定相同参数,永远返回相同的结果。快照获取原理与stable函数一致。
  • 优化器可以预估函数结果,在多次调用时仅将其当做一个值。
  • 支持创建函数索引。
  • 典型函数:计算a+b的和。

函数为什么要有execute?

  • 执行动态SQL:使用一个函数处理不同的表、列等,灵活性高。
  • 强制SQL进行硬解析:避免SQL因为数据倾斜使用错误的执行计划。

与普通SQL不同,pgsql中默认使用Plan Caching,会自动将sql以prepare方式执行,尝试生成和缓存generic plan进行软解析。但是,如果有数据倾斜问题,缓存的执行计划可能是低效的,对部分核心业务来说是不可接受的。此时可以考虑使用execute语句,强制根据每个变量值生成对应执行计划,提高准确度。

MVCC实现方式优缺点

优点

  • 无论事务进行了多少操作,事务回滚可以立即完成
  • 数据可以进行很多更新,不必像Oracle和MySQL的innodb引擎需要保证回滚段不会被用完,也不会经常遇到“ORA-1555”错误的困扰。

缺点

  • 旧版本的数据需要清理。pgsql9.x版本中已经增加了自动清理的辅助进程来定期清理。
  • 旧版本的数据可能会导致查询需要扫描的数据块增多,从而导致查询变慢。

预写日志(WAL)是什么?

所有的修改最初都被捕获到这个附加的日志中,然后才被捕获到磁盘上的数据文件中。使用预写日志记录,可以保护数据面授损坏。

和MySQL的区别是什么?

功能特性

数据类型支持
  • postgreSQL:支持丰富的数据类型,包括数组、json、jsonb、范围类型、几何类型等。对于复杂数据结构的存储和处理非常方便,例如可以直接在数据库中存储和查询json格式的数据。
  • mysql:数据类型相对传统,不如pgsql全面。

存储过程和函数

  • pgsql:提供强大的存储过程和函数语言PL/PGSQL,以及其他多种语言支持(python、C等)。可以实现复杂的业务逻辑,并且具有良好的性能和稳定性。
  • mysql:支持存储过程和函数,但功能相对较弱。实现复杂逻辑需要更多的代码和技巧。

索引

  • pgsql:支持多种索引类型,如B-Tree,哈希、GiST、SP-GiST、GIN等,可以根据不同的数据类型和查询需求选择合适的索引。例:GIN索引对于全文搜索和包含大量数组或JSON数据的查询非常有效。
  • MySQL:主要是B-Tree、哈希,在一些特殊场景下的索引选择相对较少。

事务并发和控制

  • pgsql:
  • mysql:

性能

查询性能

  • pgsql:在复杂查询和分析型工作负载下表现出色,其优化器能够更好地处理复杂的连接和子查询。
  • mysql:在某些场景下,如简单的读写操作和高并发的事务处理,可能具有更好的性能。

写入性能

  • pgsql:写入性能不错,但在某些情况下可能需要更多的资源和优化来达到与Mysql相同的写入速度。
  • MySQL:在写入性能方面可能稍占优势,尤其是在使用innodb引擎时,对大量的插入、更新和删除操作有较好的处理能力。

可扩展性

水平扩展
  • pgsql:可通过第三方工具(如Citus)实现水平扩展,将数据分布在多个节点上,提高系统的处理能力和容量。
  • mysql:有水平扩展的解决方案,如MySQL Cluster和基于中间件的扩展方式。但在实现和管理上可能相对复杂。
垂直扩展
  • 两者都可以通过增加硬件资源(如CPU、内存、存储)来提高性能和容量。但在大规模数据集和高并发情况下,可能需要更复杂的架构设计和优化。

安全性

用户权限管理

pgsql:提供惊喜的用户权限管理,可以对数据库对象进行非常具体的权限控制。例如:可以控制用户对特定表的列表级别的访问权限。

mysql:也有用户权限管理功能,但相对来说没有pgsql那么细致。

数据加密
  • 两者都支持数据加密,包括对存储在数据库中的数据进行加密和在网络传输过程中的加密。
  • pgsql在加密功能上更加灵活,可以使用多种加密算法和密钥管理方式。