PostGIS 性能调优与 PostgreSQL 工作负载的调优非常相似。唯一的额外考虑因素是几何图形和栅格通常很大,因此与 PostgreSQL 的其他类型的查询相比,与内存相关的优化通常对 PostGIS 的影响更大。
有关优化 PostgreSQL 的一般详细信息,请参阅 调优您的 PostgreSQL 服务器。
对于 PostgreSQL 9.4+,可以通过使用 ALTER SYSTEM
命令在服务器级别设置配置,而无需触及 postgresql.conf
或 postgresql.auto.conf
。
ALTER SYSTEM SET work_mem = '256MB'; -- this forces non-startup configs to take effect for new connections SELECT pg_reload_conf(); -- show current setting value -- use SHOW ALL to see all settings SHOW work_mem;
除了 Postgres 设置外,PostGIS 还有一些自定义设置,这些设置列在 第 7.22 节,“Grand Unified Custom Variables (GUCs)”中。
这些设置在 postgresql.conf
中配置
默认值:partition
这通常用于表分区。此设置的默认值设置为“partition”,这对于 PostgreSQL 8.4 及更高版本来说是理想的,因为它将强制规划器仅分析继承层次结构中的表以进行约束考虑,否则不会支付规划器的代价。
默认值:在 PostgreSQL 9.6 中约为 128MB
设置为可用 RAM 的大约 25% 到 40%。在 Windows 上,您可能无法设置得那么高。
max_worker_processes 此设置仅适用于 PostgreSQL 9.4+。对于 PostgreSQL 9.6+,此设置具有额外的意义,因为它控制您可以用于并行查询的最大进程数。
默认值:8
设置系统可以支持的最大后台进程数。此参数只能在服务器启动时设置。
work_mem - 设置用于排序操作和复杂查询的内存大小
默认值:1-4MB
对于大型数据库、复杂查询、大量 RAM,请向上调整
对于许多并发用户或低 RAM,请向下调整。
如果您有大量 RAM 和少量开发人员
SET work_mem TO '256MB';
maintenance_work_mem - 用于 VACUUM、CREATE INDEX 等的内存大小。
默认值:16-64MB
通常太低 - 在交换内存时占用 I/O,锁定对象
建议在具有大量 RAM 的生产服务器上使用 32MB 到 1GB,但这取决于并发用户的数量。如果您有大量 RAM 和少量开发人员
SET maintenance_work_mem TO '1GB';
max_parallel_workers_per_gather
此设置仅适用于 PostgreSQL 9.6+,并且只会影响 PostGIS 2.3+,因为只有 PostGIS 2.3+ 支持并行查询。如果设置为大于 0,则某些查询(例如涉及 ST_Intersects
等关系函数的查询)可以使用多个进程,并且在执行此操作时可以运行速度提高两倍以上。如果您有很多处理器可以空闲,则应将此值更改为您拥有的处理器数量。还要确保将 max_worker_processes
增加到至少与此数字一样高。
默认值:0
设置单个 Gather
节点可以启动的最大工作进程数。并行工作进程是从 max_worker_processes
建立的进程池中获取的。请注意,请求的工作进程数可能在运行时不可用。如果发生这种情况,计划将以比预期更少的工作进程运行,这可能效率低下。将此值设置为 0(默认值)将禁用并行查询执行。
如果您启用了栅格支持,您可能需要阅读以下内容,了解如何正确配置它。
从 PostGIS 2.1.3 开始,默认情况下禁用数据库外栅格和所有栅格驱动程序。为了重新启用这些,您需要在服务器环境中设置以下环境变量 POSTGIS_GDAL_ENABLED_DRIVERS
和 POSTGIS_ENABLE_OUTDB_RASTERS
。对于 PostGIS 2.2,您可以使用更跨平台的方法来设置相应的 第 7.22 节,“Grand Unified Custom Variables (GUCs)”。
如果要启用脱机栅格
POSTGIS_ENABLE_OUTDB_RASTERS=1
任何其他设置或根本不设置都将禁用数据库外栅格。
为了启用 GDAL 安装中提供的所有 GDAL 驱动程序,请按如下方式设置此环境变量
POSTGIS_GDAL_ENABLED_DRIVERS=ENABLE_ALL
如果您只想启用特定的驱动程序,请按如下方式设置环境变量
POSTGIS_GDAL_ENABLED_DRIVERS="GTiff PNG JPEG GIF XYZ"
如果您在 Windows 上,请不要引用驱动程序列表 |
设置环境变量因操作系统而异。对于通过 apt-postgresql 安装在 Ubuntu 或 Debian 上的 PostgreSQL,首选方法是编辑 /etc/postgresql/
,其中 10 指的是 PostgreSQL 的版本,main 指的是集群。10
/main
/environment
在 Windows 上,如果您作为服务运行,您可以通过系统变量进行设置,对于 Windows 7,您可以通过右键单击计算机->属性高级系统设置或在资源管理器中导航到 控制面板\所有控制面板项\系统
来访问它。然后单击 高级系统设置->高级->环境变量 并添加新的系统变量。
设置环境变量后,您需要重新启动 PostgreSQL 服务,以使更改生效。
如果您使用的是 PostgreSQL 9.1+ 并且已编译并安装了 extensions/postgis 模块,则可以使用 EXTENSION 机制将数据库转换为空间数据库。
核心 postgis 扩展包括几何图形、地理、spatial_ref_sys 以及所有函数和注释。栅格和拓扑打包为单独的扩展。
在您要以空间方式启用的数据库中运行以下 SQL 代码片段
CREATE EXTENSION IF NOT EXISTS plpgsql; CREATE EXTENSION postgis; CREATE EXTENSION postgis_raster; -- OPTIONAL CREATE EXTENSION postgis_topology; -- OPTIONAL
如果您不能或不想在 PostgreSQL 扩展目录中安装 PostGIS(例如在测试、开发或受限制的环境中),通常才需要这样做。 |
通过加载 [prefix]/share/contrib
中(在构建阶段指定)的各种 sql 文件,将 PostGIS 对象和函数定义添加到您的数据库中。
核心 PostGIS 对象(几何图形和地理类型及其支持函数)位于 postgis.sql
脚本中。栅格对象位于 rtpostgis.sql
脚本中。拓扑对象位于 topology.sql
脚本中。
对于完整的 EPSG 坐标系定义标识符集,您还可以加载 spatial_ref_sys.sql
定义文件并填充 spatial_ref_sys
表。这将允许您对几何图形执行 ST_Transform() 操作。
如果您希望向 PostGIS 函数添加注释,您可以在 postgis_comments.sql
脚本中找到它们。只需从 psql 终端窗口键入 \dd [function_name] 即可查看注释。
在终端中运行以下 Shell 命令
DB=[yourdatabase] SCRIPTSDIR=`pg_config --sharedir`/contrib/postgis-3.4/ # Core objects psql -d ${DB} -f ${SCRIPTSDIR}/postgis.sql psql -d ${DB} -f ${SCRIPTSDIR}/spatial_ref_sys.sql psql -d ${DB} -f ${SCRIPTSDIR}/postgis_comments.sql # OPTIONAL # Raster support (OPTIONAL) psql -d ${DB} -f ${SCRIPTSDIR}/rtpostgis.sql psql -d ${DB} -f ${SCRIPTSDIR}/raster_comments.sql # OPTIONAL # Topology support (OPTIONAL) psql -d ${DB} -f ${SCRIPTSDIR}/topology.sql psql -d ${DB} -f ${SCRIPTSDIR}/topology_comments.sql # OPTIONAL
升级现有的空间数据库可能很棘手,因为它需要替换或引入新的 PostGIS 对象定义。
不幸的是,并非所有定义都可以在活动数据库中轻松替换,因此有时最好的选择是转储/重新加载过程。
PostGIS 为次要或错误修复版本提供了软升级程序,为主要版本提供了硬升级程序。
在尝试升级 PostGIS 之前,始终值得备份您的数据。如果您使用 pg_dump 的 -Fc 标志,您将始终能够使用硬升级来恢复转储。
如果您使用扩展安装了数据库,则还需要使用扩展模型进行升级。如果您使用旧的 sql 脚本方式安装,则建议您将安装切换到扩展,因为不再支持脚本方式。
如果您最初使用扩展安装了 PostGIS,那么您也需要使用扩展进行升级。使用扩展进行次要升级是相当轻松的。
如果您运行的是 PostGIS 3 或更高版本,则应使用 PostGIS_Extensions_Upgrade 函数升级到您已安装的最新版本。
SELECT postgis_extensions_upgrade();
如果您运行的是 PostGIS 2.5 或更低版本,请执行以下操作
ALTER EXTENSION postgis UPDATE; SELECT postgis_extensions_upgrade(); -- This second call is needed to rebundle postgis_raster extension SELECT postgis_extensions_upgrade();
如果您安装了多个版本的 PostGIS,并且不想升级到最新版本,您可以按如下方式显式指定版本
ALTER EXTENSION postgis UPDATE TO "3.5.2dev"; ALTER EXTENSION postgis_topology UPDATE TO "3.5.2dev";
如果您收到如下错误通知
No migration path defined for … to 3.5.2dev
那么您需要备份数据库,如 第 3.3.1 节,“使用 EXTENSION 以空间方式启用数据库” 中所述创建一个新的数据库,然后在此新数据库之上还原备份。
如果您收到如下通知消息
Version "3.5.2dev" of extension "postgis" is already installed
那么一切都已是最新状态,您可以安全地忽略它。除非您尝试从开发版本升级到下一个版本(没有获得新的版本号);在这种情况下,您可以将“next”附加到版本字符串,下次您需要再次删除“next”后缀
ALTER EXTENSION postgis UPDATE TO "3.5.2devnext"; ALTER EXTENSION postgis_topology UPDATE TO "3.5.2devnext";
如果您最初安装 PostGIS 时没有指定版本,您通常可以跳过在还原之前重新安装 postgis 扩展,因为备份只具有 |
如果您要从 3.0.0 之前的版本升级 PostGIS 扩展,您将拥有一个新的扩展 postgis_raster,如果您不需要栅格支持,可以安全地删除它。您可以按如下方式删除 DROP EXTENSION postgis_raster; |
本节仅适用于那些不使用扩展安装 PostGIS 的人。如果您有扩展并尝试使用此方法升级,您将收到如下消息
can't drop … because postgis extension depends on it
注意:如果您要从 PostGIS 1.* 移动到 PostGIS 2.* 或从 PostGIS 2.* 移动到 r7409 之前的版本,则不能使用此过程,而是需要执行 硬升级。
编译并安装 (make install) 后,您应该在安装文件夹中找到一组 *_upgrade.sql
文件。您可以使用以下命令列出所有文件
ls `pg_config --sharedir`/contrib/postgis-3.5.2dev/*_upgrade.sql
依次加载它们,从 postgis_upgrade.sql
开始。
psql -f postgis_upgrade.sql -d your_spatial_database
相同的过程适用于栅格、拓扑和 sfcgal 扩展,升级文件分别名为 rtpostgis_upgrade.sql
、topology_upgrade.sql
和 sfcgal_upgrade.sql
。如果您需要它们
psql -f rtpostgis_upgrade.sql -d your_spatial_database
psql -f topology_upgrade.sql -d your_spatial_database
psql -f sfcgal_upgrade.sql -d your_spatial_database
建议您通过运行以下命令切换到基于扩展的安装
psql -c "SELECT postgis_extensions_upgrade();"
如果您找不到专门用于升级您正在使用的版本的 |
PostGIS_Full_Version 函数应通过“procs need upgrade”消息通知您需要运行这种升级。
所谓“硬升级”,指的是对启用 PostGIS 的数据库进行完全的转储/重新加载。当 PostGIS 对象的内部存储发生变化或无法进行软升级时,您需要进行硬升级。请参考发行说明附录,其中会针对每个版本说明是否需要转储/重新加载(硬升级)来进行升级。
转储/重新加载过程由 `postgis_restore` 脚本辅助完成,该脚本负责跳过转储文件中所有属于 PostGIS 的定义(包括旧的定义),允许您将模式和数据恢复到已安装 PostGIS 的数据库中,而不会出现重复符号错误或引入已弃用的对象。
有关 Windows 用户的补充说明,请访问 Windows 硬升级。
具体步骤如下:
创建一个要升级的数据库(我们称之为 olddb
)的“自定义格式”转储,包括二进制 blob (-b) 和详细 (-v) 输出。用户可以是数据库的所有者,不需要是 postgres 超级帐户。
pg_dump -h localhost -p 5432 -U postgres -Fc -b -v -f "/somepath/olddb.backup" olddb
在新数据库中全新安装 PostGIS,我们将此数据库称为 newdb
。有关如何执行此操作的说明,请参阅第 3.3.2 节,“不使用 EXTENSION 空间启用数据库(不推荐)” 和 第 3.3.1 节,“使用 EXTENSION 空间启用数据库”。
您转储中的 `spatial_ref_sys` 条目将会被恢复,但它们不会覆盖 `spatial_ref_sys` 中已存在的条目。这是为了确保官方集合中的修复能够正确地传播到恢复的数据库中。如果出于任何原因您真的想要自定义覆盖标准条目,请在创建新数据库时不要加载 `spatial_ref_sys.sql` 文件。
如果您的数据库非常旧,或者您知道您在视图和函数中使用了长期弃用的函数,您可能需要加载 legacy.sql
以使所有函数和视图等正常恢复。只有在_真的_需要时才这样做。如果可能,请考虑在转储之前升级您的视图和函数。可以通过加载 uninstall_legacy.sql
来删除已弃用的函数。
使用 `postgis_restore` 将您的备份恢复到新创建的 newdb
数据库中。如果出现意外错误,psql 会将其打印到标准错误流中。请记录这些错误。
postgis_restore "/somepath/olddb.backup" | psql -h localhost -p 5432 -U postgres newdb 2> errors.txt
以下情况下可能会出现错误:
您的一些视图或函数使用了已弃用的 PostGIS 对象。为了解决这个问题,您可以尝试在恢复之前加载 legacy.sql
脚本,或者您必须恢复到仍然包含这些对象的 PostGIS 版本,并在移植代码后再次尝试迁移。如果 legacy.sql
的方法对您有效,请不要忘记修复您的代码以停止使用已弃用的函数,并通过加载 uninstall_legacy.sql
来删除它们。
转储文件中 `spatial_ref_sys` 的一些自定义记录具有无效的 SRID 值。有效的 SRID 值大于 0 且小于 999000。999000 到 999999 范围内的值保留供内部使用,而大于 999999 的值根本不能使用。所有具有无效 SRID 的自定义记录都将被保留,其中大于 999999 的记录将被移动到保留范围内,但是 `spatial_ref_sys` 表将失去一个检查约束,该约束用于保护该不变性成立,并且可能也会失去其主键(当多个无效的 SRID 被转换为相同的保留 SRID 值时)。
为了解决这个问题,您应该将您的自定义 SRS 复制到一个具有有效值的 SRID(可能在 910000..910999 范围内),将所有表转换为新的 srid(请参阅 UpdateGeometrySRID),从 `spatial_ref_sys` 中删除无效的条目,并使用以下命令重建检查约束:
ALTER TABLE spatial_ref_sys ADD CONSTRAINT spatial_ref_sys_srid_check check (srid > 0 AND srid < 999000 );
ALTER TABLE spatial_ref_sys ADD PRIMARY KEY(srid));
如果您正在升级包含法国 IGN 制图的旧数据库,您可能会有超出范围的 SRID,并且在导入数据库时会看到类似这样的问题:
WARNING: SRID 310642222 converted to 999175 (in reserved zone)
在这种情况下,您可以尝试以下步骤:首先从 `postgis_restore` 生成的 sql 中完全删除 IGN。因此,在运行
postgis_restore "/somepath/olddb.backup" > olddb.sql
运行此命令
grep -v IGNF olddb.sql > olddb-without-IGN.sql
然后创建您的 newdb,激活所需的 Postgis 扩展,并使用以下方式正确插入法国系统 IGN:此脚本。完成这些操作后,导入您的数据。
psql -h localhost -p 5432 -U postgres -d newdb -f olddb-without-IGN.sql 2> errors.txt