空間分析的最佳做法
本文說明如何在 BigQuery 中最佳化地理空間查詢效能的最佳做法。您可以運用這些最佳做法來提升效能,並降低成本和延遲時間。
資料集可包含大量多邊形、多邊形形狀和線串集合,用於表示複雜的地圖項目,例如道路、土地地塊和洪水區。每個形狀可包含數千個點。在 BigQuery 的大部分空間運算 (例如交集和距離計算) 中,底層演算法通常會造訪每個形狀中的大多數點,以產生結果。對於某些作業,演算法會造訪所有點。對於複雜形狀,拜訪每個點都會增加空間運算的成本和時間。您可以運用本指南介紹的策略和方法,將這些常見的空間運算最佳化,以便提升效能並降低成本。
本文假設您的 BigQuery 地理空間資料表是以地理欄進行叢集。
簡化圖形
最佳做法:使用簡化和對齊格線函式,將原始資料集的簡化版本儲存為具象化檢視畫面。
許多包含大量點的複雜形狀都可以簡化,且精確度不會有太大損失。請單獨或同時使用 BigQuery ST_SIMPLIFY
和 ST_SNAPTOGRID
函式,以減少複雜形狀中的點數。將這些函式與 BigQuery 具象化檢視表結合,即可將原始資料集的簡易版本儲存為具象化檢視表,並自動根據基礎資料表保持最新狀態。
在下列用途中,簡化形狀最能有效改善資料集的成本和效能:
- 您必須確保與實際形狀高度相似。
- 您必須執行高精度、高準確度的作業。
- 您希望加快視覺化效果,但不犧牲形狀細節。
以下程式碼範例說明如何在具有名為 geom
的 GEOGRAPHY
資料欄的基礎資料表上使用 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_DISTANCE
或 ST_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 中查看地理空間資料時,輸出結果會是與錨點建築物最近的建築物形狀叢集,如以下圖所示:
在 Google Cloud 主控台中執行這項查詢時,請按一下「工作資訊」,並確認「向量索引用量模式」已設為 FULLY_USED
。這表示查詢會利用先前建立的 building_vector_index
向量索引。
分割大型圖形
最佳做法:使用 ST_SUBDIVIDE
函式分割大型圖形。
使用 ST_SUBDIVIDE
函式,將大型形狀或長字串拆成較小的形狀。
後續步驟
- 瞭解如何使用格線系統進行空間分析。
- 進一步瞭解 BigQuery 地理函式。
- 瞭解如何管理向量索引。
- 進一步瞭解 在 BigQuery 中進行空間索引和叢集的最佳做法。
- 如要進一步瞭解如何在 BigQuery 中分析及呈現地理空間資料,請參閱「開始使用地理空間分析」。