CREATE NORMAL INDEX¶
CREATE NORMAL INDEX语句用于为特定图或临时图创建普通索引。
可选择以下任意方法来指定图或临时图:
- 在本语句前添加 USE 子句来设定工作图。
- 提前使用 SESSION SET 设置当前会话的图或临时图。
若两种方法均使用,则以 USE 子句中的指定为准。若均未使用,则报错。
您可以基于单个点类型或边类型的一个或多个属性创建普通索引,从而加速基于索引属性进行的数据过滤或排序查询。
若要创建其他类型的索引,请参见 CREATE VECTOR INDEX、CREATE SPATIAL INDEX 和 CREATE FULLTEXT INDEX。
Note
对非默认 Schema 或其中的对象执行操作时,用户既要通过隐式访问规则或显式USAGE授权获得该 Schema 的访问权,也要具备目标操作所需的权限。Schema 访问校验和目标操作所需的权限校验相互独立,满足其中一项不能替代另一项。Schema 访问控制不适用于临时图、内置 Procedure 和内置 Function。更多信息,请参见 Schema 访问控制。
前提条件¶
- 已创建图或临时图。更多信息,请参见 CREATE GRAPH 和 CREATE TEMPORARY GRAPH。
- 若要在图上创建普通索引,必须是图的所有者,或具备在图上执行
INDEX操作的权限,或具备在当前 Schema 执行CREATE INDEX操作的权限。更多信息,请参见角色与权限。 - 若要在临时图上创建普通索引,必须是具备角色
ADMIN的用户或临时图的所有者。
执行机制与影响¶
- 执行
CREATE NORMAL INDEX后,系统会自动启动后台索引构建作业。该后台作业在SHOW JOB或SHOW JOBS中显示为REPAIR_INDEX作业。通常不需要再手动触发额外的修复操作才能让新索引生效。 - 在索引构建完成前,查询无法使用该新索引。
- 当索引正在构建时,读写请求可继续执行;但构建过程会消耗额外 I/O(以及一定 CPU/内存)资源,可能导致查询或写入延迟上升。
- 如果索引创建失败,系统会自动回滚本次创建。从 5.2 开始,索引创建失败会自动回滚,因此不再需要额外的索引修复操作。
语法¶
- create_index_statement
- index_property_list
create_index_statement ::=
'CREATE' 'NORMAL'? 'INDEX' ('IF NOT EXISTS')? index_name 'ON' ( ( ('NODE' | 'VERTEX') 'TYPE'? node_type_name ) | ( ('EDGE'|'RELATIONSHIP') 'TYPE'? edge_type_name ) ) '(' index_property_list ')'
index_property_list ::=
( property_name ('ASC' | 'DESC')? ) ( ',' ( property_name ('ASC' | 'DESC')? ) )*
参数¶
NORMAL¶
显式指定待创建的索引的类型为普通索引。可省略。
IF NOT EXISTS¶
该子句会检查是否已存在同名的索引。若已存在,则不会创建索引,也不会抛出异常。
若未指定该子句,且已存在同名的索引,则会抛出异常。
index_name¶
待创建的索引的名称。该名称为常规标识符,在同一个图的所有类型的索引中,索引名称必须唯一。
有关标识符的详细信息,请参见标识符命名规则。
node_type_name¶
待创建索引的点类型的名称。支持基于不同的属性为同个点类型创建多个索引。
edge_type_name¶
待创建索引的边类型的名称。支持基于不同的属性为同个边类型创建多个索引。
index_property_list¶
待创建索引的属性列表。必须至少指定一个属性。
若基于多个属性创建普通索引,索引中属性的顺序与index_property_list中属性的顺序相同。因此,在基于索引属性进行数据过滤或排序时,建议按照索引中的属性顺序编写查询语句,从而优化查询性能。
property_name¶
待创建索引的点类型或边类型的属性名称。
该属性的值类型不能为LIST、SET、MAP、VECTOR或GEOGRAPHY。
对于边类型索引,还支持使用系统字段_src(源点)和_dst(目标点)作为索引属性。将_src或_dst作为索引属性列表的首列时,即构成 Vertex-Centric 索引。详见下文 Vertex-Centric 索引。
ASC | DESC¶
索引中属性值的排序顺序。
ASC:默认值,按升序排序属性值。DESC:按降序排序属性值。
有关不同数据类型的排序规则,请参见比较谓词。
Vertex-Centric 索引¶
概念¶
Vertex-Centric 索引(点中心索引)是一种以点为中心的边索引。在图遍历场景中,从某个点出发查找其关联的边是最常见的操作之一。如果该点关联的边数量很大(例如超级点),遍历所有边并逐一过滤的代价会非常高。Vertex-Centric 索引通过在边索引的首列放置系统字段_src(源点)或_dst(目标点),使得查询能够快速定位到特定点的边,并结合后续索引列进一步过滤,从而避免全边扫描。
Vertex-Centric 索引不是一种单独的索引类型,而是普通边索引的一种特殊构建方式。创建时使用标准的CREATE NORMAL INDEX语法,只需将_src或_dst作为索引属性列表的首列即可。
适用场景¶
- 从特定起点出发查找符合条件的出边:使用
_src作为索引首列。 - 查找指向特定终点的入边:使用
_dst作为索引首列。 - 超级点的边过滤:当某个点关联大量边时,Vertex-Centric 索引可以显著减少需要扫描的边数量。
自动选择¶
当查询的WHERE子句中包含至少一个对边属性的过滤条件(例如w.rate >= 3)时,优化器可在边扫描规划阶段自动选择 Vertex-Centric 索引。具体而言,自动选择要求存在一个可用的 Vertex-Centric 索引,其键列与扫描方向匹配(出边查询使用以_src为首列的索引,入边查询使用以_dst为首列的索引),并且索引列覆盖了被过滤的边属性。满足条件时,无需手动指定索引提示。
若查询中未包含任何边属性的过滤条件(即仅通过锚点的点 ID 来定位边),优化器不会自动选择 Vertex-Centric 索引。这是因为在没有边属性过滤的情况下,Vertex-Centric 索引只能利用其首列_src/_dst,相比默认的边表前缀扫描没有额外优势。如有需要,您仍可通过显式索引提示来强制使用指定的 Vertex-Centric 索引。
使用限制¶
- 仅适用于边类型的索引,不适用于点类型的索引。
_src或_dst只能作为索引属性列表的第一列。- 不支持在无向边类型上创建 Vertex-Centric 索引。
_src开头的索引和_dst开头的索引服务于不同的查询方向。如果需要同时加速出边和入边查询,需要分别创建两个索引。- 普通索引的其他限制同样适用(例如不能对
LIST类型的属性建索引)。
示例¶
以下示例基于在 CREATE GRAPH 和 CREATE TEMPORARY GRAPH 中分别创建的图movie和临时图#movie_temporary_graph。
在图的点类型上创建普通索引¶
'''
USE movie
CREATE NORMAL INDEX IF NOT EXISTS idx_actor_age ON NODE Actor ( birthDate ASC )
'''
在点类型Actor上基于属性birthDate创建一个名为idx_actor_age的升序普通索引。
在图的边类型上创建普通索引¶
'''
USE movie
CREATE NORMAL INDEX IF NOT EXISTS idx_watch_rating ON EDGE Watch ( rate DESC )
'''
在边类型Watch上基于属性rate创建一个名为idx_watch_rating的降序普通索引。
在临时图上创建普通索引¶
'''
USE #movie_temporary_graph
CREATE NORMAL INDEX IF NOT EXISTS idx_actor_age_temp ON NODE Actor ( birthDate ASC )
'''
'''
USE #movie_temporary_graph
CREATE NORMAL INDEX IF NOT EXISTS idx_watch_rating_temp ON EDGE Watch ( rate DESC )
'''
创建 Vertex-Centric 索引¶
以_src为首列,加速从特定用户出发查找其观看记录并按评分过滤:
'''
USE movie
CREATE NORMAL INDEX IF NOT EXISTS idx_watch_src_rate ON EDGE Watch ( _src ASC, rate DESC )
'''
以_dst为首列,加速查找观看了特定电影的所有用户并按评分过滤:
'''
USE movie
CREATE NORMAL INDEX IF NOT EXISTS idx_watch_dst_rate ON EDGE Watch ( _dst ASC, rate DESC )
'''
自动选择 Vertex-Centric 索引¶
当查询包含边属性过滤条件时,优化器会自动选择合适的 Vertex-Centric 索引。
按起点查出边:
'''
PROFILE
USE movie
MATCH (a:Person)-[w:Watch]->(m:Movie)
WHERE a.id > 100 AND w.rate >= 3
RETURN m.name, w.rate
ORDER BY w.rate DESC
LIMIT 20
'''
按终点查入边:
'''
PROFILE
USE movie
MATCH (m:Movie{id:101})<-[w:Watch]-(a:Person)
WHERE a.id > 100 AND w.rate >= 3
RETURN a.id, w.rate
ORDER BY w.rate DESC
LIMIT 20
'''
使用PROFILE或EXPLAIN命令查看执行计划。如果执行计划中出现了IndexScan相关的算子,并且引用了 Vertex-Centric 索引名称(例如idx_watch_src_rate或idx_watch_dst_rate),则说明 Vertex-Centric 索引已生效。更多信息,请参见 EXPLAIN 和 PROFILE。
Note
若查询中未包含任何边属性的过滤条件(例如没有类似w.rate >= 3的条件),优化器不会自动选择 Vertex-Centric 索引。此时,您仍可通过显式索引提示来强制使用(例如MATCH (a:Person)-[w:Watch/*+ INDEX(idx_watch_src_rate) */]->(m:Movie))。有关索引提示的更多信息,请参见配置索引提示。