实例 通过执行 MySQL 命令(mysqld)启动实例。一个实例可以管理一个或多个数据库。一台服务器可以运行多个 mysqld 实例。一个实例管理器可以监视 mysqld 的各个实例。
通过执行 Postmaster 进程(pg_ctl)启动实例。一个实例可以管理一个或多个数据库,这些数据库组成一个集群。集群是磁盘上的一个区域,这个区域在安装时初始化并由一个目录组成,所有数据都存储在这个目录中。使用 initdb 创建第一个数据库。一台机器上可以启动多个实例。
数据库 数据库是命名的对象集合,是与实例中的其他数据库分离的实体。一个 MySQL 实例中的所有数据库共享同一个系统编目。 数据库是命名的对象集合,每个数据库是与其他数据库分离的实体。每个数据库有自己的系统编目,但是所有数据库共享 pg_databases。
数据缓冲区 通过 innodb_buffer_pool_size 配置参数设置数据缓冲区。这个参数是内存缓冲区的字节数,InnoDB 使用这个缓冲区来缓存表的数据和索引。在专用的数据库服务器上,这个参数最高可以设置为机器物理内存量的 80%。 Shared_buffers 缓存。在默认情况下分配 64 个缓冲区。默认的块大小是 8K。可以通过设置 postgresqlconf 文件中的 shared_buffers 参数来更新缓冲区缓存。
数据库连接 客户机使用 CONNECT 或 USE 语句连接数据库,这时要指定数据库名,还可以指定用户 id 和密码。使用角色管理数据库中的用户和用户组。 客户机使用 connect 语句连接数据库,这时要指定数据库名,还可以指定用户 id 和密码。使用角色管理数据库中的用户和用户组。
身份验证 MySQL 在数据库级管理身份验证。 基本只支持密码认证。 PostgreSQL 支持丰富的认证方法:信任认证、口令认证、Kerberos 认证、基于 Ident 的认证、LDAP 认证、PAM 认证
加密 可以在表级指定密码来对数据进行加密。还可以使用 AES_ENCRYPT 和 AES_DECRYPT 函数对列数据进行加密和解密。可以通过 SSL 连接实现网络加密。 可以使用 pgcrypto 库中的函数对列进行加密/解密。可以通过 SSL 连接实现网络加密。
审计 可以对 querylog 执行 grep。 可以在表上使用 PL/pgSQL 触发器来进行审计。
查询解释 使用 EXPLAIN 命令查看查询的解释计划。 使用 EXPLAIN 命令查看查询的解释计划。
备份、恢复和日志 InnoDB 使用写前(write-ahead)日志记录。支持在线和离线完全备份以及崩溃和事务恢复。需要第三方软件才能支持热备份。 在数据目录的一个子目录中维护写前日志。支持在线和离线完全备份以及崩溃、时间点和事务恢复。 可以支持热备份。
JDBC 驱动程序 可以从 参考资料 下载 JDBC 驱动程序。 可以从 参考资料 下载 JDBC 驱动程序。
表类型 取决于存储引擎。例如,NDB 存储引擎支持分区表,内存引擎支持内存表。 支持临时表、常规表以及范围和列表类型的分区表。不支持哈希分区表。 由于PostgreSQL的表分区是通过表继承和规则系统完成了,所以可以实现更复杂的分区方式。
索引类型 取决于存储引擎。MyISAM:BTREE,InnoDB:BTREE。 支持 B-树、哈希、R-树和 Gist 索引。
约束 支持主键、外键、惟一和非空约束。对检查约束进行解析,但是不强制实施。 支持主键、外键、惟一、非空和检查约束。
存储过程和用户定义函数 支持 CREATE PROCEDURE 和 CREATE FUNCTION 语句。存储过程可以用 SQL 和 C++ 编写。用户定义函数可以用 SQL、C 和 C++ 编写。 没有单独的存储过程,都是通过函数实现的。用户定义函数可以用 PL/pgSQL(专用的过程语言)、PL/Tcl、PL/Perl、PL/Python 、SQL 和 C 编写。
触发器 支持行前触发器、行后触发器和语句触发器,触发器语句用过程语言复合语句编写。 支持行前触发器、行后触发器和语句触发器,触发器过程用 C 编写。
系统配置文件 myconf Postgresqlconf
数据库配置 myconf Postgresqlconf
客户机连接文件 myconf pg_hbaconf
XML 支持 有限的 XML 支持。 有限的 XML 支持。
数据访问和管理服务器 OPTIMIZE TABLE —— 回收未使用的空间并消除数据文件的碎片
myisamchk -analyze —— 更新查询优化器所使用的统计数据(MyISAM 存储引擎)
mysql —— 命令行工具
MySQL Administrator —— 客户机 GUI 工具 Vacuum —— 回收未使用的空间
Analyze —— 更新查询优化器所使用的统计数据
psql —— 命令行工具
pgAdmin —— 客户机 GUI 工具
并发控制 支持表级和行级锁。InnoDB 存储引擎支持 READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ 和 SERIALIZABLE。使用 SET TRANSACTION ISOLATION LEVEL 语句在事务级设置隔离级别。 支持表级和行级锁。支持的 ANSI 隔离级别是 Read Committed(默认 —— 能看到查询启动时数据库的快照)和 Serialization(与 Repeatable Read 相似 —— 只能看到在事务启动之前提交的结果)。使用 SET TRANSACTION 语句在事务级设置隔离级别。使用 SET SESSION 在会话级进行设置。
MySQL相对于PostgreSQL的劣势:
MySQL
PostgreSQL
最重要的引擎InnoDB很早就由Oracle公司控制。目前整个MySQL数据库都由Oracle控制。
BSD协议,没有被大公司垄断。
对复杂查询的处理较弱,查询优化器不够成熟
很强大的查询优化器,支持很复杂的查询处理。
只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join)。
都支持
性能优化工具与度量信息不足
提供了一些性能视图,可以方便的看到发生在一个表和索引上的select、delete、update、insert统计信息,也可以看到cache命中率。网上有一个开源的pgstatspack工具。
InnoDB的表和索引都是按相同的方式存储。也就是说表都是索引组织表。这一般要求主键不能太长而且插入时的主键最好是按顺序递增,否则对性能有很大影响。
不存在这个问题。
大部分查询只能使用表上的单一索引;在某些情况下,会存在使用多个索引的查询,但是查询优化器通常会低估其成本,它们常常比表扫描还要慢。
不存在这个问题
表增加列,基本上是重建表和索引,会花很长时间。
表增加列,只是在数据字典中增加表定义,不会重建表
存储过程与触发器的功能有限。可用来编写存储过程、触发器、计划事件以及存储函数的语言功能较弱
除支持pl/pgsql写存储过程,还支持perl、python、Tcl类型的存储过程:pl/perl,pl/python,pl/tcl。
也支持用C语言写存储过程。
不支持Sequence。
支持
不支持函数索引,只能在创建基于具体列的索引。
不支持物化视图。
支持函数索引,同时还支持部分数据索引,通过规则系统可以实现物化视图的功能。
执行计划并不是全局共享的, 仅仅在连接内部是共享的。
执行计划共享
MySQL支持的SQL语法(ANSI SQL标准)的很小一部分。不支持递归查询、通用表表达式(Oracle的with 语句)或者窗口函数(分析函数)。
都 支持
不支持用户自定义类型或域(domain)
支持。
对于时间、日期、间隔等时间类型没有秒以下级别的存储类型
可以精确到秒以下。
身份验证功能是完全内置的,不支持 *** 作系统认证、PAM认证,不支持LDAP以及其它类似的外部身份验证功能。
支持OS认证、Kerberos 认证 、Ident 的认证、LDAP 认证、PAM 认证
不支持database link。有一种叫做Federated的存储引擎可以作为一个中转将查询语句传递到远程服务器的一个表上,不过,它功能很粗糙并且漏洞很多
有dblink,同时还有一个dbi-link的东西,可以连接到oracle和mysql上。
Mysql Cluster可能与你的想象有较大差异。开源的cluster软件较少。
复制(Replication)功能是异步的,并且有很大的局限性例如,它是单线程的(single-threaded),因此一个处理能力更强的Slave的恢复速度也很难跟上处理能力相对较慢的Master
有丰富的开源cluster软件支持。
explain看执行计划的结果简单。
explain返回丰富的信息。
类似于ALTER TABLE或CREATE TABLE一类的 *** 作都是非事务性的它们会提交未提交的事务,并且不能回滚也不能做灾难恢复
DDL也是有事务的。
PostgreSQL主要优势:
1 PostgreSQL完全免费,而且是BSD协议,如果你把PostgreSQL改一改,然后再拿去卖钱,也没有人管你,这一点很重要,这表明了PostgreSQL数据库不会被其它公司控制。oracle数据库不用说了,是商业数据库,不开放。而MySQL数据库虽然是开源的,但现在随着SUN被oracle公司收购,现在基本上被oracle公司控制,其实在SUN被收购之前,MySQL中最重要的InnoDB引擎也是被oracle公司控制的,而在MySQL中很多重要的数据都是放在InnoDB引擎中的,反正我们公司都是这样的。所以如果MySQL的市场范围与oracle数据库的市场范围冲突时,oracle公司必定会牺牲MySQL,这是毫无疑问的。
2 与PostgreSQl配合的开源软件很多,有很多分布式集群软件,如pgpool、pgcluster、slony、plploxy等等,很容易做读写分离、负载均衡、数据水平拆分等方案,而这在MySQL下则比较困难。
3 PostgreSQL源代码写的很清晰,易读性比MySQL强太多了,怀疑MySQL的源代码被混淆过。所以很多公司都是基本PostgreSQL做二次开发的。
4 PostgreSQL在很多方面都比MySQL强,如复杂SQL的执行、存储过程、触发器、索引。同时PostgreSQL是多进程的,而MySQL是线程的,虽然并发不高时,MySQL处理速度快,但当并发高的时候,对于现在多核的单台机器上,MySQL的总体处理性能不如PostgreSQL,原因是MySQL的线程无法充分利用CPU的能力。
目前只想到这些,以后想到再添加,欢迎大家拍砖。
PostgreSQL与oracle或InnoDB的多版本实现的差别
PostgreSQL与oracle或InnoDB的多版本实现最大的区别在于最新版本和历史版本是否分离存储,PostgreSQL不分,而oracle和InnoDB分,而innodb也只是分离了数据,索引本身没有分开。
PostgreSQL的主要优势在于:
1 PostgreSQL没有回滚段,而oracle与innodb有回滚段,oracle与Innodb都有回滚段。对于oracle与Innodb来说,回滚段是非常重要的,回滚段损坏,会导致数据丢失,甚至数据库无法启动的严重问题。另由于PostgreSQL没有回滚段,旧数据都是记录在原先的文件中,所以当数据库异常crash后,恢复时,不会象oracle与Innodb数据库那样进行那么复杂的恢复,因为oracle与Innodb恢复时同步需要redo和undo。所以PostgreSQL数据库在出现异常crash后,数据库起不来的几率要比oracle和mysql小一些。
2 由于旧的数据是直接记录在数据文件中,而不是回滚段中,所以不会象oracle那样经常报ora-01555错误。
3 回滚可以很快完成,因为回滚并不删除数据,而oracle与Innodb,回滚时很复杂,在事务回滚时必须清理该事务所进行的修改,插入的记录要删除,更新的记录要更新回来(见row_undo函数),同时回滚的过程也会再次产生大量的redo日志。
4 WAL日志要比oracle和Innodb简单,对于oracle不仅需要记录数据文件的变化,还要记录回滚段的变化。
PostgreSQL的多版本的主要劣势在于:
1、最新版本和历史版本不分离存储,导致清理老旧版本需要作更多的扫描,代价比较大,但一般的数据库都有高峰期,如果我们合理安排VACUUM,这也不是很大的问题,而且在PostgreSQL90中VACUUM进一步被加强了。
2、由于索引中完全没有版本信息,不能实现Coverage index scan,即查询只扫描索引,直接从索引中返回所需的属性,还需要访问表。而oracle与Innodb则可以;
进程模式与线程模式的对比
PostgreSQL和oracle是进程模式,MySQL是线程模式。
进程模式对多CPU利用率比较高。
进程模式共享数据需要用到共享内存,而线程模式数据本身就是在进程空间内都是共享的,不同线程访问只需要控制好线程之间的同步。
线程模式对资源消耗比较少。
所以MySQL能支持远比oracle多的更多的连接。
对于PostgreSQL的来说,如果不使用连接池软件,也存在这个问题,但PostgreSQL中有优秀的连接池软件软件,如pgbouncer和pgpool,所以通过连接池也可以支持很多的连接。
堆表与索引组织表的的对比
Oracle支持堆表,也支持索引组织表
PostgreSQL只支持堆表,不支持索引组织表
Innodb只支持索引组织表
索引组织表的优势:
表内的数据就是按索引的方式组织,数据是有序的,如果数据都是按主键来访问,那么访问数据比较快。而堆表,按主键访问数据时,是需要先按主键索引找到数据的物理位置。
索引组织表的劣势:
索引组织表中上再加其它的索引时,其它的索引记录的数据位置不再是物理位置,而是主键值,所以对于索引组织表来说,主键的值不能太大,否则占用的空间比较大。
对于索引组织表来说,如果每次在中间插入数据,可能会导致索引分裂,索引分裂会大大降低插入的性能。所以对于使用innodb来说,我们一般最好让主键是一个无意义的序列,这样插入每次都发生在最后,以避免这个问题。
由于索引组织表是按一个索引树,一般它访问数据块必须按数据块之间的关系进行访问,而不是按物理块的访问数据的,所以当做全表扫描时要比堆表慢很多,这可能在OLTP中不明显,但在数据仓库的应用中可能是一个问题。
PostgreSQL90中的特色功能:
PostgreSQL中的Hot Standby功能
也就是standby在应用日志同步时,还可以提供只读服务,这对做读写分离很有用。这个功能是oracle11g才有的功能。
PostgreSQL异步提交(Asynchronous Commit)的功能:
这个功能oracle中也是到oracle11g R2才有的功能。因为在很多应用场景中,当宕机时是允许丢失少量数据的,这个功能在这样的场景中就特别合适。在PostgreSQL90中把synchronous_commit设置为false就打开了这个功能。需要注意的是,虽然设置为了异步提交,当主机宕机时,PostgreSQL只会丢失少量数据,异步提交并不会导致数据损坏而数据库起不来的情况。MySQL中没有听说过有这个功能。
PostgreSQL中索引的特色功能:
PostgreSQL中可以有部分索引,也就是只能表中的部分数据做索引,create index 可以带where 条件。同时PostgreSQL中的索引可以反向扫描,所以在PostgreSQL中可以不必建专门的降序索引了。
并行查询使用多个后台进程,但后端进程基本上处理连接的客户端发出的所有查询。改后端有五个子系统组成。
解析器生成一个解析树,后续子系统可以从纯文本的 SQL 语句中读取该解析树。
如下面的查询:
解析树是其根节点是定义在 parsenodesh中的 [SelectStmt](javascript:void(0))结构的树。
SELECT 查询的元素和解析树的相应元素编号相同。例如,(1) 是第一个目标列表的一个项目,它是表的“id”列,(4) 是 WHERE 子句,依此类推。
由于解析器在生成解析树时只检查输入的语法,因此只有在查询中出现语法错误时才会返回错误。
解析器不检查输入查询的语义。例如,即使查询包含不存在的表名,解析器也不会返回错误。语义检查由分析器/分析器完成。
分析器运行由解析器生成的解析树的语义分析并生成查询树。
查询树的根是定义在 parsenodesh中的 [查询](javascript:void(0))结构;此结构包含其相应查询的元数据,例如此命令的类型(SELECT、INSERT 或其他)和几个叶子;每个叶子形成一个列表或树,并保存各个特定子句的数据。
述查询树简述如下。
重写器是实现 规则系统 的系统,必要时根据存储在 pg_rules系统目录中的规则变换查询树。
PostgreSQL 中的视图 是使用规则系统实现的。当视图由 CREATE VIEW 命令定义时,相应的规则会自动生成并存储在目录中。
假设已经定义了以下视图,并且对应的规则存储在 pg_rules 系统目录中。
当发出包含如下所示视图的查询时,解析器将创建解析树,如图所示。
在这个阶段,重写器将范围表节点处理为子查询的解析树,即对应的视图,存储在 pg_rules 中。
计划器从重写器接收查询树并生成可以由执行器最有效地处理的(查询)计划树。
PostgreSQL 中的计划器是基于纯成本优化的;它不支持基于规则的优化和提示。这个规划器是 RDBMS 中最复杂的子系统
与其他 RDBMS 一样,PostgreSQL 中的 EXPLAIN命令显示计划树本身。 如下所示。
他对应的计划树:
每个计划节点都有执行器需要处理的信息,单表查询的情况下,执行器从计划树的末端到根进行处理。
PostgreSQL 的查询优化是基于成本的。成本是无量纲值,它们不是绝对的绩效指标,而是比较运营相对绩效的指标。成本由 costsizec 中定义的函数估算。执行器执行的所有 *** 作都有相应的成本函数。例如,顺序扫描和索引扫描的成本分别由 cost_seqscan() 和 cost_index() 估算。
有三种成本,启动成本,执行成本以及总成本。其中总成本 = 启动成本 + 执行成本。
顺序扫描的成本由 cost_seqscan() 函数估算。
其中 seq_page_cost 、 cpu_tuple_cost 和 cpu_operator_cost 在 postgresqlconf 文件中设置,默认值分别为 10 、 001 和 00025 ,Ntuple和Npage分别是该表的所有元组和所有页的编号。
从运行成本估算可以看出,PostgreSQL 假设所有页面都将从存储中读取;也就是说,PostgreSQL 不考虑扫描的页面是否在共享缓冲区中。
虽然 PostgreSQL 支持 一些索引方法 ,例如 BTree、 GiST 、 GIN 和 BRIN ,但索引扫描的成本是使用常见的成本函数估算的:cost_index()。
索引扫描的启动成本是读取索引页以访问目标表中第一个元组的成本,它由以下等式定义:
Hindex是索引树的高度。
索引扫描的运行成本是表和索引的 cpu 成本和 IO(输入/输出)成本之和:
前三个成本定义如下:
其中 cpu_index_tuple_cost 和 random_page_cost 在 postgresqlconf 文件中设置(默认分别为 0005 和 40); qual_op_cost粗略来说就是指数的评估成本,值为00025。选择性选择性是指定WHERE子句对索引的搜索范围的比例;它是一个从 0 到 1 的浮点数
查询谓词的选择率是通过直方图界值与高频值估计的,这些信息都储存在系统目录pg_staticstics中,并可通过pg_stats视图查询。
表中的每一列的高频值都在pg_stats视图的most_common_vals和most_common_freqs中成对存储。
排序路径会在排序 *** 作中被使用。排序 *** 作包括order by、归并连接的预处理 *** 作,以及其他函数。函数cost_sort()用于估计排序 *** 作的代价。如果能在工作内存中放下所有元组,那么排序 *** 作会选用快速排序算法。否则就会创建临时文件,使用文件归并排序算法。
排序路径的启动代价就是对目标表的排序代价,因此代价就是O(Nsort) Log 2 (Nsort),这里Nsort就是带排序的元组数。排序路径的运行代价就是读取已经排序好的元组的代价,因此代价就是O(Nsort)。
PostgreSQL中的计划器会执行三个步骤:
访问路径是估算代价时的处理单元。比如顺序扫描、索引扫描、排序,以及各种连接 *** 作都有其对应的路径。访问路径只在计划器创建查询计划树的时候使用。最忌本的访问路径数据结构就是relationh中定义的path结构体,相当于顺序扫描。所有其他的路径访问都基于该结构。
在创建计划树之前,计划器将线对PlannerInfo中的查询书进行一些预处理。预处理有很多步骤,本节值讨论和单表查询处理相关的主要步骤。
计划器对所有可能的访问路径进行代价估计,然后选择代价最小的那个。
在最后一步中,计划器按照代价最小的路径生成一颗计划树。
计划树的根节点是定义在plannodesh中的Plannedstmt结构,包含19个字段,其中有4个代表性字段:
计划树包含各式各样的计划节点。PlanNode是所有计划节点的基类,其他计划节点都会包含PlanNode结构。比如顺序扫描节点SeqScanNode包含一个PlanNode和一个整型变量scanrelid。PlanNode包含14个字段,下面是7个代表性字段:
在单表查询的例子中,执行器从计划树中取出计划节点,按照自底向上的顺序进行处理,并调用节点相应的处理函数。
每个计划节点都有相应的函数,用于执行节点对应的 *** 作。这些函数在src/backend/executor目录中。
理解执行器如何工作的最好方式,就是阅读explain命令的输出。
我们可以自底向上阅读explain的结果,来看一看执行器是如何工作的。
第六行:首先,执行器通过nodeSeqscanc中定义的函数执行顺序扫描 *** 作。
第四行:然后,执行器通过nodeSortc中定义的函数,对顺序扫描的结果进行排序。
执行器在处理查询时会使用工作内存和临时缓冲区,两者都在内存中分配。如果查询无法在内存中完成,就会用到临时文件。
使用带有Analyze选项的explain,待解释的命令会真正执行,并显示实际结果行数、实际执行时间和实际内存使用量。
在第6行,explain命令显示执行器使用了10000KB的临时文件。临时文件会被临时创建在base/pg_tmp子目录中,并遵循如下命令规则:{“pgsql_tmp”}+ {创建本文件的postgres进程pid}{从0开始的序列号}
比如,临时文件pgsql_tmp89035是pid为8903的postgres进程创建的第6个临时文件。
PostgreSQL中支持三种连接 *** 作,分别是嵌套循环连接,归并连接和散列连接。在pg中,嵌套循环连接和归并连接有几种变体。
这三种连接方式都支持pg中所有的连接 *** 作,注入inner join、 left/right outer join、 full outer join等。
循环嵌套连接不需要任何启动代价,因此:start-up cost = 0
运行代价和内外表尺寸的乘积成比例,即run cost是O(Nouter Ninner), Nouter和Ninner分别是外表和内表的元组条数。run cost的定义如下:
Couter和Cinner分别是内表和外表顺序扫描的代价。
循环嵌套连接的代价总会被估计,但实际中很少会使用这种连接 *** 作,因为它有几种更高效的变体。
在上面描述的循环嵌套连接中,每当读取一条外表中的元组时,都需要扫描内标中的所有元组。位每条外表元组对内标做全表扫描,这一过程代价高昂,pg支持一种物化嵌套循环连接,可以减少内标全表扫描的代价。
在运行嵌套循环连接之前,执行器会使用临时元组存储模块对内表进行一次扫描,将内表元组加载到工作或临时文件中。在处理内表元组时,临时元组存储比缓冲区管理器更为高效,特别是当所有的元组都能放入工作内存中。
qg内部提供了临时元组存储的模块,可用于各种 *** 作,如五花膘、创建混合散列连接的批次等。该模块包含一系列函数,都在tuplestorec中。这些函数用于从工作内存或临时文件读写元组。该工作内存还是临时文件取决于待存储元组的总数。
上面显示了执行器要进行的 *** 作,执行器对这些计划节点的处理过程如下:
第7行:执行器使用顺序扫描,物化内部表tbl_b。
第4行:执行器执行嵌套循环连接 *** 作,外表是tbl_a,内表是物化的tbl_b。
如果内表上有索引,且该索引能用于搜索满足连接条件的元组,那么计划器在外外表的每条元组搜索内标中的匹配元组时,会考虑使用索引进行直接搜索,以替代顺序扫描。这种变体叫做索引嵌套循环连接,如下图所示。虽然这种变体叫做“索引嵌套循环连接”,但是谁该算法基本上只需要在外表上循环一次,因此连接 *** 作的执行非常高效。
与嵌套循环连接不同的是,归并连接只能用于自然连接与等值连接。
函数initial_cost_merge_join()和final_cost_merge_join()用于估计归并连接的代价。
归并连接的启动成本是内表与外表排序成本之和,因此其启动成本为:
这里Nouter和Ninner分别是外表和内标的元素条数,而运行代价是O(Nouter + Ninner)。
下图是归并连接的示意图。
如果所有元组都可以存储在内存中,那么排序 *** 作就能在内存中进行,否则就是用临时文件。
第9行:执行器对内表tbl_b进行排序,使用顺序扫描(第11行)。
第6行:执行器对外表tbl_a进行排序,使用顺序扫描(第8行)。
第4行:执行器执行归并连接 *** 作,外表是排序好的tbl_a,内表是排好序的tbl_b。
与嵌套循环连接类似,归并连接还支持物化归并连接,物化内表,使内表扫描更为高效。
下面是物化归并连接的explain结果,很容易发现,与普通归并连接的差异是第9行:Materialize。
与归并连接类似,hash连接只能用于自然连接与等值连接。
PostgreSQL中的散列连接的行为因表的大小而异。如果布标足够小(确切的说,内表大小不超过工作内存的25%),那么hash连接就是简单的两阶段内存hash连接,否则将会使用带倾斜批次的混合hash连接。
内存中的hash连接是在work_mem中处理的,在pg中,散列表区域被称作处理批次。一个批处理批次会有多个散列槽,内部称其为桶,桶的数量由nodeHashc中定义的ExecChooseHashTableSize()函数所确定。桶的数量是2的整数次幂。
内存散列连接有两个阶段,分别是构建阶段和探测阶段。在构建阶段,内存表中的所有元组都会被插入到处理批次中;在探测阶段每条腕表元组都会与处理批次中的内表元组比较,如果满足连接条件,则将两条元组连接起来。
当内表的元组无法全部存储在工作内表中的单个处理批次时,pg使用带倾斜批次的混合散列连接算法,该算法时混合散列连接诶的一种变体。
在第一个构建和探测阶段postgresql准备多个批次,宇通的数目类似,处理批次的数据由函数ExecChooseHashTableSize()决定,也就是2的整数次幂。工作内存中智慧分配一个处理批次,而其他批次都以临时文件的形式创建。属于这些批次的元组将通过临时元组存储功能被写入到相应的文件中。
为了获取最佳计划树,计划器必须考虑各个索引与各种连接方法之间的所有可能组合。如果表的数量超过某个水平,该过程的代价就会因为组合爆炸而变得非常昂贵,以至于根本不可行。
如果表的数量小于12张,计划器可以使用动态规划来获取最佳计划。
一、 PostgreSQL 的稳定性极强, Innodb 等引擎在崩溃、断电之类的灾难场景下抗打击能力有了长足进步,然而很多 MySQL 用户都遇到过Server级的数据库丢失的场景——mysql系统库是MyISAM的,相比之下,PG数据库这方面要好一些。
二、任何系统都有它的性能极限,在高并发读写,负载逼近极限下,PG的性能指标仍可以维持双曲线甚至对数曲线,到顶峰之后不再下降,而 MySQL 明显出现一个波峰后下滑(55版本之后,在企业级版本中有个插件可以改善很多,不过需要付费)。
三、PG 多年来在 GIS 领域处于优势地位,因为它有丰富的几何类型,实际上不止几何类型,PG有大量字典、数组、bitmap 等数据类型,相比之下mysql就差很多,instagram就是因为PG的空间数据库扩展POSTGIS远远强于MYSQL的my spatial而采用PGSQL的。
四、PG 的“无锁定”特性非常突出,甚至包括 vacuum 这样的整理数据空间的 *** 作,这个和PGSQL的MVCC实现有关系。
五、PG 的可以使用函数和条件索引,这使得PG数据库的调优非常灵活,mysql就没有这个功能,条件索引在web应用中很重要。
以上就是关于MySQL与PostgreSQL比较 哪个数据库更好全部的内容,包括:MySQL与PostgreSQL比较 哪个数据库更好、pg查询处理流程、对比其他数据库软件,postgresql有什么优势等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)