【问题标题】:One JOIN works slower than two same SELECT一个 JOIN 的工作速度比两个相同的 SELECT 慢
【发布时间】:2017-09-07 09:16:17
【问题描述】:

我有这个问题:

SELECT *
FROM placex AS place
WHERE ST_DWithin(geometry, (SELECT geometry FROM placex WHERE place_id = 412369), 300)
AND name->'name' = (SELECT name->'name' FROM placex WHERE place_id = 412369)

前置时间:530-650ms

这个查询使用两个 SELECT,它很丑,我想用连接重写。但是这个查询:

SELECT same.*
FROM placex AS same
JOIN placex AS place ON place.place_id = 412369
WHERE ST_DWithin(same.geometry, place.geometry, 300)
AND same.name->'name' = place.name->'name';

在 2.8 秒内完成。所有索引都默认保留(由 Nominatim 提供)。如何优化第二个查询?还是先用再不用担心?

PostgreSQL 9.6.4,POSTGIS 2.3.3 r15473

EXPLAIN (ANALYZE, BUFFERS)

【问题讨论】:

  • 添加指向 EXPLAIN(分析,缓冲区)的链接
  • 如果您查看EXPLAIN ANALYZE 的输出,您会发现它们不是等效查询; JOIN 版本产生 25 行,而子选择版本产生 1。

标签: postgresql postgis nominatim


【解决方案1】:

我猜不出原因,但我认为您可以尝试像这样重写您的第二个查询

SELECT same.* 
FROM   placex AS same 
       JOIN (SELECT name, 
                    geometry 
             FROM   placex 
             WHERE  place_id = 412369) AS place 
         ON ST_DWithin(same.geometry, place.geometry, 300) 
            AND same.name->'name' = place.name->'name'; 

或者您可以将您的第一个查询重写为

SELECT * 
FROM   placex AS place 
WHERE  EXISTS 
       ( 
              SELECT 1 
              FROM   placex AS same 
              WHERE  same.place_id = 412369 
              AND    ST_DWithin(place.geometry, same.geometry, 300) 
              AND    same.name->'name' = place.name->'name');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多