格網編碼查詢方案在項目運用上的進一步探索

文章版權由做者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/sql

1.背景

在上一篇博客中我提到了格網編碼的兩個優勢:緩存

  • 將兩個整形(地理)字段的查詢變成了一個整形字段的查詢
  • 經過合理的劃分格網能夠將多個條件查詢(左上、右下構成的四個查詢條件)優化成多數狀況下的一個查詢條件(等於一個格網編碼)

可是,實際項目上,這種優化效果明顯嗎?微信

2.實際測試

2.1以不一樣大小的表測試

  • 經過構造範圍查詢 SQL
select * from tc_geo_address a where a.coordinate_x>504625 and a.coordinate_x<504825 and a.coordinate_y>309858 and a.coordinate_y<310058
  • 經過地理編碼查詢 SQL
select * from tc_geo_address a where a.grid_code=3300000110

其中coordinate_x和coordinate_y以及grid_code上都創建了索引 對比結果:markdown

表大小 範圍查詢 單個編碼查詢
2K條 0.002S 0.002S
17W條 1.08S 0.84S

2.2總結

  • 只有表足夠大時,單編碼查詢纔有優點
  • 當多個地理編碼組成組合查詢時,效率可能會比範圍查詢低

3.緩存優化(當查詢表內容固定,如興趣點查詢)

3.1爲何能夠開啓查詢緩存?

  • 格網編碼的原理:將地圖進行網格切分,在地圖範圍、切割大小必定的狀況下,格網的個數是固定。
  • 格網查詢的原理:針對查詢的XY和範圍構造出其覆蓋的全部格網編碼,最後依然變成了以格網編碼的查詢。
  • 結論:雖然XY座標是沒法作緩存的(不斷變化),可是其解析對應的格網編碼是固定的,每一次格網編碼所對應的查詢結果也是固定的。因此咱們能夠對格網編碼查詢後的結果進行緩存。

3.2方案實現

3.2.1網格查詢結果緩存

爲了提升緩存命中度,咱們以單個格網編碼爲主鍵進行緩存:app

/***  * 經過傳入網格編碼進行搜索,提供緩存功能  * @param gridcodefield  * @param gridcode  * @return  */ @Cacheable(value="cacheOneHour",key="'getaddcode'+#gridcode+#gridcodefield") public List<GeoAddress> getAddressBySingleCode(String gridcodefield,String gridcode){ try{ if(gridcodefield.equals("")){ gridcodefield="Grid_Code"; } String sql=gisConfigManager.getSQL("GeoCode.GeoCodeReverseGridCode"); sql+=" where "+gridcodefield+"="+gridcode; return jdbcTemplate.query(sql,new Object[]{},new DataRowMapper(GeoAddress.class)); }catch(Exception e){ return null; } }

3.2.2查詢範圍分塊格網請求

List<Long> searchResult=GridCodeUtils.GridCodeSearch(OperConst.MapBounds.get(0), OperConst.MapBounds.get(1), x, y, gridsize, gridsize, radius); if(searchResult==null){ LogUtils.error("查詢地理編碼結果爲空!", logger,null); return null; } //分開利用code查詢是爲了充分製造緩存命中 for(int i=0;i<searchResult.size();i++){ List<GeoAddress> temAddList=cacheManager.getAddressBySingleCode(gridHashField,searchResult.get(i).toString()); if(temAddList!=null&&temAddList.size()>0){ list.addAll(temAddList); } }

4.若是附帶屬性查詢條件?(當表內容固定)

以上僅僅是根據座標去進行過濾查詢。若是附帶上對查詢結果的進一步條件篩選呢? 這類狀況分幾種狀況進行討論。工具

4.1過濾條件十分固定——歸入緩存

好比:查詢條件永遠都是離目前範圍500M的視頻。
那麼針對編碼查詢時同樣能夠歸入緩存機制中。測試

4.2過濾條件常態化變更

4.2.1格網(無屬性過濾)對應的查詢結果很少——先格網查詢緩存、再過濾結果

好比:查詢條件會不斷變化,多是500M內的視頻,多是500M內的井蓋等等。能夠先進行格網編碼查詢並緩存,再對查詢結果依據查詢條件進行過濾:優化

//由於address常常變化,不利於緩存,因此用代碼進行過濾 if(address!=""){//查詢條件過濾 List<GeoAddress> addlist=new ArrayList<GeoAddress>(); for(int i=0;i<list.size();i++){ GeoAddress addressObj=list.get(i); if(addressObj.getAddress().contains(address)){ addlist.add(addressObj); } } }

4.2.1格網(無屬性過濾)對應的查詢結果十分多

  • 查詢表能夠重構:將大表改爲小表,使得格網查詢結果變少,那麼以上方案依然可用。
  • 查詢表沒法重構:實時sql查詢。

5.當查詢表內容不斷更新

此時緩存機制可能致使數據不是最新的,依然需sql進行查詢。ui

6.輔助編碼工具

當咱們想使用編碼機制而存入的數據只有XY沒有編碼值時,這裏咱們針對性開發了一個地理編碼賦值工具:
編碼

 

                    -----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/

                                                                          若是您以爲本文確實幫助了您,能夠微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^

                                      

相關文章
相關標籤/搜索