完全可行,但必须配合st_geomfromtext()或st_point()等构造函数,不能将wkt当普通字符串插入geometry字段;需显式指定srid,推荐批量用copy+st_makepoint,插入后及时vacuum和analyze。

INSERT INTO ... VALUES 中直接写 WKT 字符串是否可行?
完全可行,但必须配合 ST_GeomFromText() 或 ST_Point() 等构造函数,不能把 WKT 当普通字符串插入 geometry 字段。PostgreSQL 的 geometry 列不接受裸文本,否则会报错:column "geom" is of type geometry but expression is of type text。
常见错误是这样写:
INSERT INTO places (name, geom) VALUES ('A', 'POINT(120.1 30.2)');
正确写法必须显式转换:
INSERT INTO places (name, geom) VALUES ('A', ST_GeomFromText('POINT(120.1 30.2)', 4326));
-
ST_GeomFromText()第二个参数是 SRID,强烈建议显式指定(如4326),否则默认为 0,后续空间查询可能失效 - 若数据全是点且坐标规整,用
ST_Point(x, y)更快、更安全(自动绑定 SRID):ST_Point(120.1, 30.2, 4326) - WKT 字符串里空格和括号必须严格,
'POINT(120.1,30.2)'(逗号)会解析失败
大批量导入时,用 INSERT ... SELECT FROM VALUES 还是 COPY?
优先用 COPY,尤其当数据源是 CSV 或内存中已组织好的行集。单条 INSERT 插入万级几何对象可能慢 5–10 倍,因为每行都触发函数调用、SRID 检查和索引更新。
实操建议:
- 把原始坐标整理成 CSV(例如
name,x,y),再用COPY导入临时表,最后一次性转 geometry:COPY temp_coords (name, x, y) FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true);<br>INSERT INTO places (name, geom)<br>SELECT name, ST_SetSRID(ST_MakePoint(x, y), 4326)<br>FROM temp_coords;
- 如果只能走 SQL(比如从应用层拼语句),用
VALUES批量 +ST_MakePoint组合比ST_GeomFromText快:后者要解析字符串,前者直接数值计算 - 避免在
VALUES里混用不同 SRID,ST_SetSRID(ST_MakePoint(...), srid)比多次调用ST_GeomFromText(..., srid)更轻量
批量插入后空间索引没生效?别忘了 VACUUM 和 ANALYZE
即使你执行了 CREATE INDEX ON places USING GIST (geom),刚插入大量数据后,查询仍可能走全表扫描——因为 PostgreSQL 的统计信息还没更新,优化器不知道新数据分布。
关键动作:
- 插入完成后立即运行:
VACUUM places(清理死元组,释放空间) - 紧接着运行:
ANALYZE places(更新列统计,让查询计划器知道geom列有新数据) - 如果插入前已有空间索引,无需重建;但若中途禁用了索引(比如为提速临时
DROP INDEX),插入完必须CREATE INDEX回来 - 用
EXPLAIN (ANALYZE, BUFFERS)查看实际是否命中索引,别只看EXPLAIN的预估
从 GeoJSON 或其他格式转批量插入,绕不开 jsonb 和函数链
PostgreSQL 12+ 可直接解析 GeoJSON 字符串,但要注意嵌套层级和坐标顺序(GeoJSON 是 [lon, lat],WGS84 下对应 x, y)。
例如有一列存 GeoJSON Feature 对象的 jsonb,想批量抽点:
INSERT INTO places (name, geom)<br>SELECT <br> data->>'name',<br> ST_SetSRID(<br> ST_MakePoint(<br> (data->'geometry'->'coordinates')->>0, -- lon<br> (data->'geometry'->'coordinates')->>1 -- lat<br> ),<br> 4326<br> )<br>FROM (SELECT '{"type":"Feature","properties":{"name":"B"},"geometry":{"type":"Point","coordinates":[120.1,30.2]}}'::jsonb AS data) AS t;
-
jsonb路径提取用->和->>,后者返回 text,适合喂给ST_MakePoint - GeoJSON 的
coordinates是数组,->>0取第一个元素(字符串),需确保它可转 float,否则ST_MakePoint报错 - 多点、线、面类型需先判断
data->'geometry'->>'type',再分支处理,不能硬写->'coordinates'
真正麻烦的是坐标系混杂或含 Z/M 值——这时候别硬撑,先用 Python 或 GDAL 预处理,再进库。SQL 不是万能解析器。










