|
| 1 | +--- |
| 2 | +title: CREATE SPATIAL INDEX |
| 3 | +sidebar_position: 1 |
| 4 | +--- |
| 5 | + |
| 6 | +在 Databend 中创建新的空间索引。 |
| 7 | + |
| 8 | +## 语法 |
| 9 | + |
| 10 | +```sql |
| 11 | +CREATE [ OR REPLACE ] SPATIAL INDEX [IF NOT EXISTS] <index> |
| 12 | + ON [<database>.]<table>( <geometry_column>[, <geometry_column> ...] ) |
| 13 | +``` |
| 14 | + |
| 15 | +| 参数 | 描述 | |
| 16 | +|-----------|-------------| |
| 17 | +| `[ OR REPLACE ]` | 如果索引已存在,则替换已有索引。 | |
| 18 | +| `[ IF NOT EXISTS ]` | 仅在同名索引不存在时创建索引。 | |
| 19 | +| `<index>` | 空间索引的名称。 | |
| 20 | +| `[<database>.]<table>` | 包含被索引列的表。 | |
| 21 | +| `<geometry_column>` | 要加入索引的 `GEOMETRY` 列。语句中列名不能重复。 | |
| 22 | + |
| 23 | +## 使用说明 |
| 24 | + |
| 25 | +- 空间索引仅支持 Fuse 表。 |
| 26 | +- 空间索引仅支持 `GEOMETRY` 列,不支持 `GEOGRAPHY` 列。 |
| 27 | +- 一个空间索引定义中可以包含多个列,这些列都必须是 `GEOMETRY` 类型。 |
| 28 | + |
| 29 | +## 示例 |
| 30 | + |
| 31 | +创建包含空间列的表: |
| 32 | + |
| 33 | +```sql |
| 34 | +CREATE TABLE stores ( |
| 35 | + store_id INT, |
| 36 | + store_name STRING, |
| 37 | + location GEOMETRY |
| 38 | +) ENGINE = FUSE; |
| 39 | +``` |
| 40 | + |
| 41 | +在 `location` 列上创建空间索引: |
| 42 | + |
| 43 | +```sql |
| 44 | +CREATE SPATIAL INDEX stores_location_idx ON stores(location); |
| 45 | +``` |
| 46 | + |
| 47 | +查看表定义: |
| 48 | + |
| 49 | +```sql |
| 50 | +SHOW CREATE TABLE stores; |
| 51 | + |
| 52 | +┌──────────────────────────────────────────────────────────────────────────────────────────────┐ |
| 53 | +│ Table │ Create Table │ |
| 54 | +├──────────────────────────────────────────────────────────────────────────────────────────────┤ |
| 55 | +│ stores │ CREATE TABLE stores ( │ |
| 56 | +│ │ store_id INT NULL, │ |
| 57 | +│ │ store_name VARCHAR NULL, │ |
| 58 | +│ │ location GEOMETRY NULL, │ |
| 59 | +│ │ SYNC SPATIAL INDEX stores_location_idx (location) │ |
| 60 | +│ │ ) ENGINE=FUSE │ |
| 61 | +└──────────────────────────────────────────────────────────────────────────────────────────────┘ |
| 62 | +``` |
| 63 | + |
| 64 | +插入一些用于空间过滤的示例数据: |
| 65 | + |
| 66 | +```sql |
| 67 | +INSERT INTO stores VALUES |
| 68 | + (1, 'Starbucks', TO_GEOMETRY('POINT(10 10)')), |
| 69 | + (2, 'Costa', TO_GEOMETRY('POINT(11 11)')), |
| 70 | + (3, 'Gong Cha', TO_GEOMETRY('POINT(20 20)')), |
| 71 | + (4, 'Dunkin', TO_GEOMETRY('POINT(-10 -10)')); |
| 72 | +``` |
| 73 | + |
| 74 | +### 使用 `ST_WITHIN`、`ST_INTERSECTS` 和 `ST_CONTAINS` 过滤 |
| 75 | + |
| 76 | +这些谓词是常见的 geofence 场景过滤条件,通常都可以从空间索引中受益。 |
| 77 | + |
| 78 | +```sql |
| 79 | +-- 查询位于多边形内部的位置 |
| 80 | +SELECT store_id, store_name |
| 81 | +FROM stores |
| 82 | +WHERE ST_WITHIN( |
| 83 | + location, |
| 84 | + TO_GEOMETRY('POLYGON((9 9, 9 12, 12 12, 12 9, 9 9))') |
| 85 | +) |
| 86 | +ORDER BY store_id; |
| 87 | +``` |
| 88 | + |
| 89 | +```sql |
| 90 | +-- 查询与多边形相交的位置 |
| 91 | +SELECT store_id, store_name |
| 92 | +FROM stores |
| 93 | +WHERE ST_INTERSECTS( |
| 94 | + location, |
| 95 | + TO_GEOMETRY('POLYGON((9 9, 9 12, 12 12, 12 9, 9 9))') |
| 96 | +) |
| 97 | +ORDER BY store_id; |
| 98 | +``` |
| 99 | + |
| 100 | +```sql |
| 101 | +-- 查询被多边形包含的点 |
| 102 | +SELECT store_id, store_name |
| 103 | +FROM stores |
| 104 | +WHERE ST_CONTAINS( |
| 105 | + TO_GEOMETRY('POLYGON((9 9, 9 12, 12 12, 12 9, 9 9))'), |
| 106 | + location |
| 107 | +) |
| 108 | +ORDER BY store_id; |
| 109 | +``` |
| 110 | + |
| 111 | +### 使用 `ST_DWITHIN` 按距离过滤 |
| 112 | + |
| 113 | +`ST_DWITHIN` 适合做半径范围查询,例如“查找附近位置”。 |
| 114 | + |
| 115 | +```sql |
| 116 | +SELECT store_id, store_name |
| 117 | +FROM stores |
| 118 | +WHERE ST_DWITHIN( |
| 119 | + location, |
| 120 | + TO_GEOMETRY('POINT(10 10)'), |
| 121 | + 1.5 |
| 122 | +) |
| 123 | +ORDER BY store_id; |
| 124 | +``` |
| 125 | + |
| 126 | +### 在空间 Join 中过滤 |
| 127 | + |
| 128 | +当 Join 条件是受支持的空间谓词时,空间索引同样有帮助。 |
| 129 | + |
| 130 | +```sql |
| 131 | +CREATE TABLE districts ( |
| 132 | + district_id INT, |
| 133 | + district_name STRING, |
| 134 | + geom GEOMETRY |
| 135 | +) ENGINE = FUSE; |
| 136 | + |
| 137 | +INSERT INTO districts VALUES |
| 138 | + (1, 'Central', TO_GEOMETRY('POLYGON((8 8, 8 13, 13 13, 13 8, 8 8))')), |
| 139 | + (2, 'West', TO_GEOMETRY('POLYGON((-2 -2, -2 2, 2 2, 2 -2, -2 -2))')); |
| 140 | +``` |
| 141 | + |
| 142 | +```sql |
| 143 | +SELECT d.district_name, s.store_name |
| 144 | +FROM districts AS d |
| 145 | +JOIN stores AS s |
| 146 | + ON ST_WITHIN(s.location, d.geom) |
| 147 | +ORDER BY d.district_name, s.store_name; |
| 148 | +``` |
0 commit comments