将逻辑上的一个大表分成一些小的物理上的片。(能够提高查询性能,方便批量数据操作——整个分区)
当前支持的分区方法是范围、列表以及哈希
无法把一个常规表转换成分区表,反之亦然。(单个分区和表之间的转换)
分区表及其分区不会参与到与常规表的继承关系中
由于分区表并不直接拥有任何数据,尝试在分区表上使用TRUNCATE ONLY将总是返回错误。
更新行的分区键可能导致它满足另一个不同的分区的分区边界,进而被移动到那个分区中。
可以在分区的表上创建索引,并自动将其应用于整个层次结构。 这非常便利,因为不仅现有分区将变为索引,而且将来创建的任何分区都将变为索引。
一个限制是,在创建这样一个分区索引时,不可能同时使用CONCURRENTLY限定符。 为了克服长时间锁,可以对分区表使用CREATE INDEX ON ONLY ;
这样的索引被标记为无效,并且分区不会自动应用该索引。 分区上的索引可以使用CONCURRENTLY分别的创建。
然后使用ALTER INDEX .. ATTACH PARTITIONattached到父索引。 一旦所有分区的索引附加到父索引,父索引将自动标记为有效。
分区裁剪是一种提升声明式分区表性能的查询优化技术。例如:
SET enable_partition_pruning = on; -− the default
SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01';
应该谨慎地选择如何划分表,因为查询规划和执行的性能可能会受到不良设计的负面影响。
最重要的设计决策之一是列或者如和对数据进行分区的。 通常最佳选择是按列或列集合进行分区,这些列最常出现在分区表上执行的查询的 WHERE子句中。 WHERE子句项与分区键匹配并兼容,可用于裁剪不需要的分区。 但是,你可能会被迫根据PRIMARY KEY或UNIQUE约束的要求做出其他决策。 在规划分区策略时,删除不需要的数据也是需要考虑的一个因素。 可以相当快地分离整个分区,因此采用这样方式设计分区策略可能是有益的,既把一次删除的所有数据都放在单个分区中。
选择表应该划分的分区的目标数量也是一个重要的决策。 没有足够的分区可能意味着索引仍然太大,数据位置仍然较差,这可能导致缓存命中率很低。 但是,将表划分为太多的分区也会导致问题。 在查询规划和执行期间,过多的分区可能意味着查询计划时间较长,内存消耗也更高。 在选择如何划分表时,考虑将来可能发生的更改也很重要。 例如,如果您选择为每个客户提供一个分区,而您目前只有少量的大客户,那么,如果几年后您发现自己有大量的小客户,那么就要考虑这种影响。 在这种情况下,最好选择按HASH分区并且选择合理数量的分区,而不是尝试按 LIST 进行分区,并希望客户数量的增长不会超出按数据分区的实际范围。
子分区可用于进一步划分预期会比其他分区更大的分区,尽管过多的子分区很容易导致大量分区,并可能导致前一段中提到的相同问题。
考虑查询计划和执行期间的分区开销也很重要。 查询规划器通常能够很好地处理多达几千个分区的分区层次结构,前提是典型的查询允许查询规划器裁剪除了少量分区之外的所有分区。 规划器执行分区修剪后保留更多分区时,规划时间会变长,内存消耗会更高。对于UPDATE 和 DELETE命令尤其如此。 担心拥有大量分区的另一个原因是,服务器的内存消耗可能会在一段时间内显著增加,特别是如果许多会话接触大量分区。 这是因为每个分区都需要将其元数据加载到接触它的每个会话的本地内存中。
对于数据仓库类型工作负载,使用比 OLTP 类型工作负载更多的分区数量很有意义。 通常,在数据仓库中,查询计划时间不太值得关注,因为大多数处理时间都花在查询执行期间。对于这两种类型的工作负载,尽早做出正确的决策非常重要,因为重新分区大量数据可能会非常缓慢。 模拟预期工作负载通常有利于优化分区策略。永远不要假设更多的分区比更少的分区更好,反之亦然。
外部数据:
要访问外部数据,我们需要建立一个外部服务器对象,它根据它所支持的外部数据包装器所使用的一组选项定义了如何连接到一个特定的外部数据源。
接着我们需要创建一个或多个外部表,它们定义了外部数据的结构。一个外部表可以在查询中像一个普通表一样地使用,但是在PostgreSQL服务器中外部表没有存储数据。不管使用什么外部数据包装器,PostgreSQL会要求外部数据包装器从外部数据源获取数据,或者在更新命令的情况下传送数据到外部数据源。