跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

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
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 ,

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))。有关索引提示的更多信息,请参见配置索引提示。