针对PostGIS性能进行的调优与针对任何PostgreSQL工作负载进行的调优非常相似。唯一需要注意的是,几何图形和栅格通常都很大,因此与内存相关的优化通常比其他类型的PostgreSQL查询对PostGIS的影响更大。
有关优化PostgreSQL的一般详细信息,请参阅 调整您的PostgreSQL服务器 。
对于PostgreSQL 9.4+,无需接触即可在服务器级别设置配置 postgresql.conf
或 postgresql.auto.conf
通过使用 ALTER SYSTEM
指挥部。
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还具有中列出的一些自定义设置 Section 8.23, “大统一自定义变量(GUC)” 。
这些设置在中配置 postgresql.conf
:
默认:分区
这通常用于表分区。默认设置为“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 -真空、创建索引等使用的内存大小。
默认:16-64MB
通常过低-占用I/O,在交换内存时锁定对象
建议在具有大量RAM的生产服务器上使用32MB到1 GB,但这取决于并发用户数。如果您有大量的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,您可以使用更具跨平台的方法来设置相应的 Section 8.23, “大统一自定义变量(GUC)” 。
如果要启用脱机栅格,请执行以下操作:
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中,你可以通过右击Computer- > 属性高级系统设置或在资源管理器中导航到 Control Panel\All Control Panel Items\System
。然后点击 高级系统设置- > 高级->环境变量 以及添加新的系统变量。
设置环境变量后,需要重新启动PostgreSQL服务才能使更改生效。
如果您使用的是PostgreSQL9.1+,并且已经编译和安装了扩展/postgis模块,则可以使用扩展机制将数据库转换为空间数据库。
核心的Postgis扩展包括几何、地理、空间参考系统以及所有的函数和注释。栅格和拓扑被打包为单独的扩展。
在要在空间上启用的数据库中运行以下SQL代码片段:
CREATE EXTENSION IF NOT EXISTS plpgsql; CREATE EXTENSION postgis; CREATE EXTENSION postgis_raster; -- OPTIONAL CREATE EXTENSION postgis_topology; -- OPTIONAL
![]() | |
通常只有当您不能或不想在PostgreSQL扩展目录中安装PostGIS时(例如,在测试、开发期间或在受限环境中),才需要这样做。 |
将PostGIS对象和函数定义添加到数据库中的方法是加载位于 [prefix]/share/contrib
如在构建阶段指定的。
核心PostGIS对象(几何和地理类型及其支持函数)位于 postgis.sql
剧本。栅格对象位于 rtpostgis.sql
剧本。拓扑对象位于 topology.sql
剧本。
对于一组完整的EPSG坐标系定义标识符,还可以将 spatial_ref_sys.sql
定义文件并填充 spatial_ref_sys
数据表。这将允许您对几何体执行ST_Transform()操作。
如果您想要向PostGIS函数添加注释,可以在 postgis_comments.sql
剧本。只需输入以下内容即可查看评论 \dd [function_name] 从一个 psql 终端窗口。
在您的终端中运行以下外壳命令:
DB=[yourdatabase] SCRIPTSDIR=`pg_config --sharedir`/contrib/postgis-3.2/ # 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的Win32安装程序 > =1.1.5)将PostGIS函数加载到名为 template_postgis
。如果 template_postgis
数据库存在于您的PostgreSQL安装中,则用户和/或应用程序可以使用单个命令创建空间启用的数据库。请注意,在这两种情况下,数据库用户都必须被授予创建新数据库的权限。
从外壳中:
# createdb -T template_postgis my_spatial_db
来自SQL:
postgres=# CREATE DATABASE my_spatial_db TEMPLATE=template_postgis
升级现有的空间数据库可能很棘手,因为它需要替换或引入新的PostGIS对象定义。
遗憾的是,并不是所有的定义都可以在实时数据库中轻松替换,所以有时您最好的选择是转储/重新加载过程。
PostGIS为次要或错误修复版本提供了软升级过程,为主要版本提供了硬升级过程。
在尝试升级PostGIS之前,备份您的数据总是值得的。如果您使用-fc标志来pg_ump,您将始终能够通过硬升级恢复转储。
如果您使用扩展安装数据库,则还需要使用扩展模型进行升级。如果您使用旧的SQL脚本方式安装,建议您将安装切换到扩展,因为脚本方式不再受支持。
如果您最初安装的是带有扩展的PostGIS,那么您也需要使用扩展进行升级。用扩展进行一个小的升级是相当容易的。
如果您运行的是PostGIS3或更高版本,则应使用 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.3.0dev"; ALTER EXTENSION postgis_topology UPDATE TO "3.3.0dev";
如果收到类似以下内容的错误通知:
No migration path defined for … to 3.3.0dev
然后,您需要备份数据库,创建一个新的数据库,如中所述 Section 3.3.1, “使用扩展在空间上启用数据库” 然后在这个新数据库上恢复备份。
如果您收到如下通知消息:
Version "3.3.0dev" of extension "postgis" is already installed
那么一切都已经是最新的,您可以放心地忽略它。 UNLESS 您正在尝试从开发版本升级到下一个版本(没有获得新的版本号);在这种情况下,您可以在版本字符串后附加“Next”,下一次您将需要再次删除“Next”后缀:
ALTER EXTENSION postgis UPDATE TO "3.3.0devnext"; ALTER EXTENSION postgis_topology UPDATE TO "3.3.0devnext";
![]() | |
如果最初安装的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.3.0dev/*_upgrade.sql
依次加载它们,从 postgis_upgrade.sql
。
psql -f postgis_upgrade.sql -d your_spatial_database
同样的过程也适用于栅格、拓扑和sfcga扩展模块,升级文件的名称为 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.pl脚本的帮助,该脚本负责从转储跳过属于PostGIS(包括旧定义)的所有定义,允许您将模式和数据恢复到安装了PostGIS的数据库中,而不会出现重复的符号错误或转发不推荐使用的对象。
有关Windows用户的补充说明,请访问 Windows硬件升级 。
具体步骤如下:
为您想要升级的数据库创建一个“定制格式”的转储文件(我们称之为 olddb
)包括二进制斑点(-b)和详细(-v)输出。用户可以是数据库的所有者,不需要是postgres超级帐户。
pg_dump -h localhost -p 5432 -U postgres -Fc -b -v -f "/somepath/olddb.backup" olddb
在新数据库中全新安装PostGIS--我们将该数据库称为 newdb
。请参阅 Section 3.3.2, “在不使用扩展的情况下在空间上启用数据库(不鼓励)” 和 Section 3.3.1, “使用扩展在空间上启用数据库” 获取有关如何执行此操作的说明。
将恢复在转储中找到的SPATIAL_REF_SYS条目,但不会覆盖SPATIAL_REF_SYS中的现有条目。这是为了确保官方集中的修复将被正确地传播到恢复的数据库。如果出于任何原因,您确实希望覆盖自己的标准条目,那么在创建新的数据库时,不要加载spatial_ref_sys.sql文件。
如果您的数据库真的很旧,或者您知道您在视图和函数中使用了长期不推荐使用的函数,则可能需要加载 legacy.sql
以便您的所有函数和视图等都能正常恢复。只有在真的需要时才这样做。如果可能的话,在转储之前考虑升级您的视图和功能。不推荐使用的函数稍后可以通过加载 uninstall_legacy.sql
。
将您的备份恢复到新的 newdb
使用postgis_Restore.pl的数据库。意外错误(如果有)将由psql打印到标准错误流中。把这些都记下来。
perl utils/postgis_restore.pl "/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值时)。
In order to fix this you should copy your custom SRS to a SRID with a valid value (maybe in the 910000..910999 range), convert all your tables to the new srid (see 更新几何SRID), delete the invalid entry from spatial_ref_sys and re-construct the check(s) with:
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));
If you are upgrading an old database containing french IGN cartography, you will have probably SRIDs out of range and you will see, when importing your database, issues like this :
WARNING: SRID 310642222 converted to 999175 (in reserved zone)
In this case, you can try following steps : first throw out completely the IGN from the sql which is resulting from postgis_restore.pl. So, after having run :
perl utils/postgis_restore.pl "/somepath/olddb.backup" > olddb.sql
run this command :
grep -v IGNF olddb.sql > olddb-without-IGN.sql
Create then your newdb, activate the required Postgis extensions, and insert properly the french system IGN with : this script After these operations, import your data :
psql -h localhost -p 5432 -U postgres -d newdb -f olddb-without-IGN.sql 2> errors.txt