PostGIS 性能调优与任何 PostgreSQL 工作负载的调优非常相似。唯一需要额外考虑的是,几何和栅格通常很大,因此与内存相关的优化通常对 PostGIS 的影响比其他类型的 PostgreSQL 查询更大。
有关优化 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.24 节,“全局统一自定义变量 (GUC)” 中。
这些设置在 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
对于大型数据库、复杂查询和大量内存,请向上调整。
对于多个并发用户或内存不足,请向下调整。
如果您有大量内存和很少的开发人员
SET work_mem TO '256MB';
maintenance_work_mem - 用于 VACUUM、CREATE INDEX 等的内存大小。
默认值:16-64MB
通常太低 - 会占用 I/O,在交换内存时锁定对象
建议在具有大量内存的生产服务器上使用 32MB 到 1GB,但这取决于并发用户的数量。如果您有大量内存和很少的开发人员
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.24 节,“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 扩展包括 geometry、geography、spatial_ref_sys 以及所有函数和注释。栅格和拓扑作为单独的扩展进行打包。
在您要启用空间功能的数据库中运行以下 SQL 代码段
CREATE EXTENSION IF NOT EXISTS plpgsql; CREATE EXTENSION postgis; CREATE EXTENSION postgis_raster; -- OPTIONAL CREATE EXTENSION postgis_topology; -- OPTIONAL
这通常仅在您无法或不想将 PostGIS 安装在 PostgreSQL 扩展目录中时才需要(例如在测试、开发或受限环境中)。 |
通过加载构建阶段指定的 [prefix]/share/contrib
中的各种 sql 文件,将 PostGIS 对象和函数定义添加到您的数据库中。
核心 PostGIS 对象(geometry 和 geography 类型及其支持函数)位于 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.3/ # 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 为次要或错误修复版本提供 SOFT UPGRADE 过程,为主要版本提供 HARD UPGRADE 过程。
在尝试升级 PostGIS 之前,始终值得备份您的数据。如果您使用 -Fc 标志到 pg_dump,您将始终能够使用 HARD UPGRADE 恢复转储。
如果您使用扩展安装了数据库,则也需要使用扩展模型进行升级。如果您使用旧的 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.4.3dev"; ALTER EXTENSION postgis_topology UPDATE TO "3.4.3dev";
如果您收到类似以下的错误通知
No migration path defined for … to 3.4.3dev
那么您需要备份您的数据库,创建一个新的数据库,如 第 3.3.1 节,“使用 EXTENSION 使数据库具有空间功能” 中所述,然后将您的备份恢复到这个新数据库上。
如果您收到类似以下的通知消息
Version "3.4.3dev" of extension "postgis" is already installed
那么一切都已更新,您可以安全地忽略它。 除非 您尝试从开发版本升级到下一个版本(没有新的版本号);在这种情况下,您可以将“next”附加到版本字符串,下次您需要再次删除“next”后缀
ALTER EXTENSION postgis UPDATE TO "3.4.3devnext"; ALTER EXTENSION postgis_topology UPDATE TO "3.4.3devnext";
如果您最初安装 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.* 或从 r7409 之前的 PostGIS 2.* 迁移,则无法使用此过程,而是需要进行 硬升级。
编译和安装(make install)后,您应该在安装文件夹中找到一组 *_upgrade.sql
文件。您可以使用以下命令列出所有文件:
ls `pg_config --sharedir`/contrib/postgis-3.4.3dev/*_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
然后创建您的新数据库,激活所需的 Postgis 扩展,并使用以下命令正确插入法国系统 IGN: 此脚本 这些操作完成后,导入您的数据
psql -h localhost -p 5432 -U postgres -d newdb -f olddb-without-IGN.sql 2> errors.txt