2008-08-30 51 views
1

在postgis中,ST_GeomFromText的調用非常昂貴嗎?我主要問的是因爲我有一個經常被調用的查詢,它試圖找到最接近另一個匹配某個條件的點的點,而且這個點也在另一個點的某個距離內,以及我目前寫它的方式,它正在執行相同ST_GeomFromText兩次:ST_GeomFromText的價格是多少

$findNearIDMatchStmt = $postconn->prepare(
    "SELECT  internalid " . 
    "FROM  waypoint " . 
    "WHERE  id = ? AND " . 
    "   category = ? AND ". 
    "   (b.category in (1, 3) OR type like ?) AND ". 
    "   ST_DWithin(point, ST_GeomFromText(?," . SRID . 
    "   ),". SMALL_EPSILON . ") " . 
    "   ORDER BY ST_Distance(point, ST_GeomFromText(?,", SRID . 
    "   )) " . 
    "   LIMIT 1"); 

有沒有更好的方法來重寫這個?

稍微OT:在預覽屏幕中,我所有的下劃線都被渲染爲& # 9 5 ; - 我希望這不會在帖子中顯示出來。

回答

1

我不認爲ST_GeomFromText()是特別昂貴的,儘管過去我通過創建一個函數來優化查詢,聲明一個變量,然後將ST_GeomFromText的結果賦值給變量。

您是否嘗試過使用各種不同的參數檢查執行計劃以查詢各種不同的參數,因爲這應該會給您一個關於查詢的哪些位花費時間的明確想法?

我猜大部分的執行時間將在ST_DWithin()ST_Distance()的調用中,但如果id和category列沒有被索引,那麼它可能會做一些有趣的表掃描。

1

@Ubiguch 看來,ST_DWithin使用空間索引,所以似乎很快就減少了要查詢的點數。

navaid=> explain select internalid from waypoint where id != 'KROC' AND ST_DWithin(point,                 ST_GeomFromText('POINT(-77.6723888888889 43.1188611111111)',4326), 0.05) order by st_distance(point, st_geomfromtext('POINT(-77.6723888888889 43.1188611111111)',4326)) limit 1; 
                                                                 QUERY PLAN                                                              
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=8.37..8.38 rows=1 width=104) 
    -> Sort (cost=8.37..8.38 rows=1 width=104) 
     Sort Key: (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry)) 
     -> Index Scan using waypoint_point_idx on waypoint (cost=0.00..8.36 rows=1 width=104) 
       Index Cond: (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) 
       Filter: (((id)::text <> 'KROC'::text) AND (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) AND ('0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry && st_expand(point, 0.05::double precision)) AND (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry) < 0.05::double precision)) 
(6 rows) 

沒有order bylimit,它看起來像一個典型的查詢只返回5-10航點最多。所以我可能不應該擔心應用於返回點的過濾器的額外成本。

+1

+1顯示如何使用`explain`來獲取數字而不是信念。 [我怎樣才能使用psql來計算SQL查詢](http://dba.stackexchange.com/questions/3148/how-can-i-time-sql-queries-using-psql)在過早優化之前,Q&A可能值得探索套入。 – jwd630 2016-07-13 20:42:34

相關問題