全部產品
Search
文件中心

Lindorm:時空查詢的效能調優

更新時間:Jul 06, 2024

為了提高時空查詢的效能,需要確保查詢條件能夠使用到時空索引,從而避免全表掃描。本文介紹時空查詢的最佳化方法。

時空查詢的最佳化

當查詢條件只有空間範圍或者包含空間範圍和時間範圍時,建立時空索引需要使用Z-ORDER索引函數對空間列或者時間列進行時空編碼,即Z-ORDER(geometry)或者Z-ORDER(geometry,time)類型。在查詢語句中請注意以下幾點:
  • Z-ORDER索引函數的入參會影響時空查詢的效能,查詢條件中必須包含Z-ORDER索引函數的所有列,才能使用時空索引。
  • 如果Z-ORDER索引函數對空間範圍和時間範圍組合進行時空編碼,那麼查詢條件中必須同時包含時間的上限和下限,才能使用時空索引。
下表列舉了不同的Z-ORDER索引函數類型對查詢操作的影響,其中g為空白間類型的列,t為時間類型的列。
查詢條件查詢語句Z-ORDER(g)Z-ORDER(g,t)
只有空間範圍SELECT id FROM point_table WHERE ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'),g);可以使用Z-ORDER索引函數加速查詢。不能使用Z-ORDER索引函數加速查詢,因為Z-ORDER索引函數是對g和t建立的索引,查詢條件必須同時包含空間範圍和時間範圍才能使用時空索引。
包含空間範圍和時間範圍SELECT id FROM point_table WHERE ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'),g) AND t>'2021-01-01 08:21:00' AND t<'2021-01-01 08:23:00';可以使用Z-ORDER索引函數加速查詢。可以使用Z-ORDER索引函數加速查詢。
SELECT id FROM point_table WHERE ST_Contains(ST_GeomFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'),g) AND t > '2021-01-01 08:21:00';可以使用Z-ORDER索引函數加速查詢。不能使用Z-ORDER索引函數加速查詢,因為時間條件不是閉合範圍。

組合查詢的最佳化

如果查詢條件中包含時空範圍和其他列,為了加快時空查詢的速度,建議構建複合式索引。複合式索引是指主鍵索引或者二級索引中包含Z-ORDER索引函數和其他列,例如PRIMARY KEY(Z-ORDER(g,t), id)。由於Z-ORDER索引函數返回的是一個編碼值,可以將Z-ORDER當作一列。關於Lindorm寬表的複合式索引介紹,請參見查詢最佳化

並行查詢的最佳化

在開啟並行查詢的條件下,可以使用Sharding來提高並行查詢的並行度,從而提高查詢效能。

Sharding是指將資料進行分區的方法。建立時空索引時使用Sharding可以使資料更加分散。同時,使用Sharding可以在寫入資料時將空間或時空相鄰的資料寫入到索引表的不同位置,進而寫入到資料庫實體儲存體的不同分區中。

您可以通過Z-ORDER索引函數,為資料類型為點(Point)的列建立時空索引,並指定索引分區(Shard)的數量numShards,即Z-ORDER(Point, numShards)。指定numShards後,索引值相鄰的numShards條資料前會被依次加上0 - numShards-1首碼,並被寫入到索引表的不同位置。

以下樣本對比了使用Sharding前後的查詢效率:

使用Sharding前:
  1. 對於資料類型為Point,資料量約為1.5億的樣本表,建立不設定numShards參數的空間索引表table_noshard。
    CREATE TABLE table_noshard(id INT, g GEOMETRY(POINT), name VARCHAR, PRIMARY KEY(Z-ORDER(g)));
  2. 對空間索引表table_noshard開啟並行查詢。
    SELECT /*+_l_enable_parallel_(8)*/ id FROM table_noshard WHERE ST_Contains(ST_GeomFromText('POLYGON((...))'), g);

    返回結果為2058894,耗時10986ms

使用Sharding後:
  1. 建立對照組。對同一樣本表,建立numShards值為8的空間索引表table_shard8。
    CREATE TABLE table_shard8(id INT, g GEOMETRY(POINT), name VARCHAR, PRIMARY KEY(Z-ORDER(g, 8)));
  2. 對空間索引表table_shard8開啟並行查詢。
    SELECT /*+_l_enable_parallel_(8)*/ id FROM table_shard8 WHERE ST_Contains(ST_GeomFromText('POLYGON((...))'), g);

    返回結果為2058894,耗時2501ms

可以看到,兩種方式的返回結果完全相同,但設定了numShards參數後並行查詢的耗時明顯縮短,查詢效率大幅提升。

不規則範圍查詢的最佳化

建立時空索引後,當查詢範圍的形狀與其矩形外包框(索引過濾範圍)相差較大時,索引過濾的效果並不理想,如下圖所示。不規則範圍查詢

當資料量較大時,可以通過設定HINT的/*+_l_enable_enhanced_filter_*/ 參數來開啟索引過濾增強功能。

例如,為表gtest(g列已建立時空索引,POLYGON((...))為不規則範圍)開啟索引過濾增強功能:
SELECT /*+_l_enable_enhanced_filter_*/ id FROM gtest WHERE ST_Contains(ST_GeomFromText('POLYGON((...))'), g);
說明 索引過濾增強功能預設不開啟,在資料量較小的情況下無需使用。