空間分析的最佳做法

本文說明如何在 BigQuery 中最佳化地理空間查詢效能的最佳做法。您可以運用這些最佳做法來提升效能,並降低成本和延遲時間。

資料集可包含大量多邊形、多邊形形狀和線串集合,用於表示複雜的地圖項目,例如道路、土地地塊和洪水區。每個形狀可包含數千個點。在 BigQuery 的大部分空間運算 (例如交集和距離計算) 中,底層演算法通常會造訪每個形狀中的大多數點,以產生結果。對於某些作業,演算法會造訪所有點。對於複雜形狀,拜訪每個點都會增加空間運算的成本和時間。您可以運用本指南介紹的策略和方法,將這些常見的空間運算最佳化,以便提升效能並降低成本。

本文假設您的 BigQuery 地理空間資料表是以地理欄進行叢集

簡化圖形

最佳做法:使用簡化和對齊格線函式,將原始資料集的簡化版本儲存為具象化檢視畫面。

許多包含大量點的複雜形狀都可以簡化,且精確度不會有太大損失。請單獨或同時使用 BigQuery ST_SIMPLIFYST_SNAPTOGRID 函式,以減少複雜形狀中的點數。將這些函式與 BigQuery 具象化檢視表結合,即可將原始資料集的簡易版本儲存為具象化檢視表,並自動根據基礎資料表保持最新狀態。

在下列用途中,簡化形狀最能有效改善資料集的成本和效能:

  • 您必須確保與實際形狀高度相似。
  • 您必須執行高精度、高準確度的作業。
  • 您希望加快視覺化效果,但不犧牲形狀細節。

以下程式碼範例說明如何在具有名為 geomGEOGRAPHY 資料欄的基礎資料表上使用 ST_SIMPLIFY 函式。程式碼會簡化圖形並移除點,但不會使圖形的任何邊緣偏離超過 1.0 公尺的指定容差。

CREATE MATERIALIZED VIEW project.dataset.base_mv
  CLUSTER BY geom
AS (
  SELECT
    * EXCEPT (geom),
    ST_SIMPLIFY(geom, 1.0) AS geom
  FROM base_table
)

以下程式碼範例說明如何使用 ST_SNAPTOGRID 函式將點對齊解析度為 0.00001 度的格線:

CREATE MATERIALIZED VIEW project.dataset.base_mv
  CLUSTER BY geom
AS (
  SELECT
    * EXCEPT (geom),
    ST_SNAPTOGRID(geom, -5) AS geom
  FROM base_table
)

這個函式中的 grid_size 引數會做為指數,代表 10e-5 = 0.00001。在赤道地區,這個解析度相當於最糟糕的情況,也就是約 1 公尺。

建立這些檢視表後,請使用查詢基礎資料表時相同的查詢語義查詢 base_mv 檢視表。您可以使用這項技術快速找出需要進一步分析的形狀集合,然後對基礎資料表執行第二次深入分析。測試查詢,找出最適合資料的門檻值。

針對評估用途,請判斷用途所需的精確度等級。使用 ST_SIMPLIFY 函式時,請將 threshold_meters 參數設為所需的準確度等級。如要以城市或更大範圍來測量距離,請將閾值設為 10 公尺。在較小規模的情況下 (例如測量建築物與最近水源之間的距離),建議使用 1 公尺以下的較小閾值。使用較低的閾值值,會從指定形狀中移除較少的點。

透過網路服務提供地圖圖層時,您可以使用 bigquery-geotools 專案為不同縮放等級預先計算具象化檢視畫面。這是 Geoserver 的驅動程式,可讓您透過 BigQuery 提供空間圖層。這個驅動程式會使用不同的 ST_SIMPLIFY 閾值參數建立多個具體化檢視表,以便在較高縮放等級提供較少細節。

使用點和矩形

最佳做法:將形狀縮減為點或矩形,以代表其位置。

您可以將形狀縮減為單一點或矩形,藉此提升查詢效能。本節中的各項方法無法準確呈現形狀的細節和比例,而是針對呈現形狀的位置進行最佳化。

您可以使用形狀的地理中心點 (其重心) 代表整個形狀的位置。使用包含形狀的矩形建立形狀的範圍,您可以使用該範圍代表形狀的位置,並保留其相對大小的資訊。

當您需要評估兩個地點 (例如兩個城市) 之間的距離時,使用點和矩形最有助於改善資料集的成本和效能。

例如,您可以將美國土地地段資料庫載入 BigQuery 資料表,然後判斷最近的水體。在這種情況下,使用 ST_CENTROID 函式預先計算區塊重心,並搭配本文件「簡化形狀」一節所述的方法,就能減少使用 ST_DISTANCEST_DWITHIN 函式時執行的比較次數。使用 ST_CENTROID 函式時,計算時必須考量到區塊的圓心。以這種方式預先計算區塊重心,也可以減少成效的變化,因為不同區塊形狀可能含有不同數量的點。

這個方法的變化版本是使用 ST_BOUNDINGBOX 函式,而非 ST_CENTROID 函式,計算輸入圖形周圍的矩形包函。雖然這不如使用單一點來得有效率,但可以減少某些邊緣情況的發生。由於 ST_BOUNDINGBOX 函式的輸出內容一律只包含四個需要考量的點,因此這個變化版本仍可提供良好且一致的效能。邊界框結果的類型為 STRUCT,這表示您必須手動計算距離,或使用本文稍後所述的向量索引方法

使用外殼

最佳做法:使用殼線,以最佳方式呈現形狀的位置。

假設您要為形狀進行縮放包裝並計算縮放包裝的邊界,則該邊界稱為外殼。在凸包中,產生的形狀的所有角度都是凸的。與形狀的範圍相同,凸包會保留一些關於基礎形狀相對大小和比例的資訊。不過,使用包絡盒的缺點是,您需要在後續分析中儲存及考量更多點。

您可以使用 ST_CONVEXHULL 函式,針對形狀的位置進行最佳化。使用這個函式可提高準確度,但效能會隨之降低。ST_CONVEXHULL 函式與 ST_EXTENT 函式相似,但輸出形狀包含更多點,且點數會根據輸入形狀的複雜度而異。雖然對於非複雜形狀的小型資料集而言,效能優勢可能微乎其微,但對於包含大型複雜形狀的超大型資料集,ST_CONVEXHULL 函式可在成本、效能和準確度之間取得良好平衡。

使用格線系統

最佳做法:使用地理空間格線系統來比較區域。

如果您的用途涉及匯總特定區域內的資料,並比較這些區域的統計匯總資料,您可以利用標準化的格線系統來比較不同區域。

舉例來說,零售商可能會想分析商店所在地區或考慮設立新店的地區,在一段時間內的客層變化。或者,保險公司可能想分析特定地區的自然災害風險,進一步瞭解財產風險。

使用 S2 和 H3 等標準格線系統,可加快這類統計匯總和空間分析作業。使用這些格狀系統也可以簡化數據分析的開發作業,並提高開發效率。

舉例來說,使用美國人口普查區進行比較時,會出現大小不一致的情況,因此必須套用修正因子,才能在人口普查區之間進行類比比較。此外,人口普查區和其他行政區的邊界會隨著時間變動,因此需要花費心力進行修正。使用空間分析的格線系統可解決這類問題。

使用向量搜尋和向量索引

最佳做法:針對最近鄰地理空間查詢使用向量搜尋和向量索引。

我們在 BigQuery 中推出向量搜尋功能,以便支援機器學習用途,例如語意搜尋、相似度偵測和檢索增強生成。啟用這些用途的關鍵,就是使用稱為近似最鄰近搜尋的索引方法。您可以使用向量搜尋,比較代表空間中點的向量,藉此加快及簡化最鄰近地理空間查詢。

您可以使用向量搜尋功能,依半徑搜尋地圖上的地圖項目。首先,請為搜尋範圍設定半徑。您可以在最近鄰搜尋的結果集中找到最佳半徑。建立半徑後,請使用 ST_DWITHIN 函式找出附近的要素。

舉例來說,您可以找出距離特定錨點建築物最近的十棟建築物,您可以將每棟建築物的重心儲存為新資料表中的向量、為資料表建立索引,然後使用向量搜尋功能進行搜尋。

在這個範例中,您也可以使用 BigQuery 中的 Overture Maps 資料,建立與感興趣區域和名為 geom_vector 的向量相對應的建築物形狀個別資料表。本範例的興趣區域是美國維吉尼亞州諾福克市,其 FIPS 代碼為 51710,如以下程式碼範例所示:

CREATE TABLE geo-solution-demos.vector_search.norfolk_buildings
AS (
  SELECT
    *,
    [
      ST_X(ST_CENTROID(building.geometry)),
      ST_Y(ST_CENTROID(building.geometry))] AS geom_vector
  FROM geo-solution-demos.overture_maps.building AS building
  INNER JOIN bigquery-public-data.geo_us_boundaries.counties AS county
    ON (st_intersects(county.county_geom, building.geometry))
  WHERE county.county_fips_code = '51710'
)

以下程式碼範例說明如何在資料表上建立向量索引:

CREATE
  vector index building_vector_index
ON
  `geo-solution-demos.vector_search.norfolk_buildings`(geom_vector)
  OPTIONS (index_type = 'IVF')

這項查詢會找出距離特定錨點建築物最近的 10 棟建築物,並以 anchor_building_id 表示:

declare anchor_building_id STRING;

SET anchor_building_id = '08b2af6202ce5fff02007d1778948bc4';

SELECT base.*
FROM
  VECTOR_SEARCH(
    TABLE `geo-solution-demos.vector_search.norfolk_buildings`,
    'geom_vector',
    (
      SELECT
        geom_vector
      FROM
        `geo-solution-demos.vector_search.norfolk_buildings`
      WHERE id = anchor_building_id
    ),
    top_k => 10,
    distance_type => 'EUCLIDEAN',
    options => '{"fraction_lists_to_search":0.1}')

BigQuery Geo Viz 中查看地理空間資料時,輸出結果會是與錨點建築物最近的建築物形狀叢集,如以下圖所示:

在 BigQuery Geo Viz 中以視覺化方式呈現地理空間資料。

在 Google Cloud 主控台中執行這項查詢時,請按一下「工作資訊」,並確認「向量索引用量模式」已設為 FULLY_USED。這表示查詢會利用先前建立的 building_vector_index 向量索引。

分割大型圖形

最佳做法:使用 ST_SUBDIVIDE 函式分割大型圖形。

使用 ST_SUBDIVIDE 函式,將大型形狀或長字串拆成較小的形狀

後續步驟