概述
索引,或属性索引,是嬴图中用于加速查找具有特定属性的点或边的技术。通过避免对整个图的全量扫描,索引帮助数据库快速定位相关数据。这在处理大型图数据时尤为重要。
索引类型
嬴图支持对单个属性创建单一索引,或对同一Schema的多个属性创建复合索引。
显示索引
显示当前图集的点索引信息:
SHOW NODE INDEX
显示当前图集的边索引信息:
SHOW EDGE INDEX
索引信息展示在表_nodeIndex
和_edgeIndex
中,包含以下字段:
字段 |
描述 |
---|---|
id |
索引ID |
name |
索引名称 |
properties |
索引关联属性 |
schema |
索引关联属性所在Schema |
status |
索引当前状态,包括DONE 和CREATING |
创建索引
使用CREATE INDEX
语句可创建一个索引。请注意,每个属性只能有一个索引。索引创建操作以作业形式进行,稍后可使用SHOW JOB <id?>
确认索引是否成功创建。
为提升查询性能,嬴图中的系统属性已完成优化,具有内建效率。这些属性不支持创建索引。
<create index statement> ::=
"CREATE INDEX" <index name> "ON" < "NODE" | "EDGE" > <schema name>
"(" <property index item> [ { "," <property index item> }... ] ")"
<property index item> ::=
<property name> [ "(" <bytes> ")" ]
详情
- 对
<index name>
而言,点索引不可重名,边索引也不可重名,但点索引可以和边索引重名。 - 对于单一索引,指定单个
<property index item>
;对于复合索引,列出多个<property index item>
。 - 如果指定属性的类型为
string
或text
,可指定给每个值创建索引的最大字节[1]数(从左算起)。忽略时,string
类型默认1024
字节,text
类型默认2048
字节。了解字符串字节长度限制如何影响查询。
[1] 标准英文文本中,大多数编码(如 ASCII或UTF-8)的每个字符使用1个字节。非英文字符的大小可能有所不同。例如,一个中文字符的大小为3字节。
为点card
的属性balance
创建名为cBalance
的单一索引:
CREATE INDEX cBalance ON NODE card (balance)
为点card
的属性name
(string
类型)创建名为name
的单一索引,并限制最大查询字符串长度为10
:
CREATE INDEX name ON NODE card (name(10))
为边transfer
的属性amount
和notes
(text
类型,限制最大查询字符串长度为10
)创建名为transAmountNotes
的复合索引:
CREATE INDEX transAmountNotes ON EDGE transfer (amount, notes(10))
删除索引
使用语句DROP NODE INDEX
或DROP EDGE INDEX
删除索引。删除索引不会影响存储在分片中的真实属性值。
拥有索引的属性无法被删除。删除属性需要先删除索引。
删除点索引cBalance
:
DROP NODE INDEX cBalance
删除边索引transAmountNotes
:
DROP EDGE INDEX transAmountNotes
使用索引
适用的查询
当以下类型的查询用到相关属性时,索引自动被应用。其他类型的查询不使用索引。
1. 使用单个点模式检索点。例如:
CREATE INDEX user_age_index ON NODE user (age)
以下查询中索引user_age_index
有效:
MATCH (n:user {age: 45}) RETURN n
MATCH (n) WHERE n.age > 45 RETURN n
第二个查询没有指定标签,因此只有查询在搜索user
点时,索引user_age_index
才生效。
2. 使用一步路径模式检索边。例如:
CREATE INDEX links_weight_index ON EDGE links (weight)
以下查询中索引links_weight_index
有效:
MATCH ()-[e:links WHERE e.weight = 2]->() RETURN e
边方向可以是向左(<-[]-
)、向右(-[]->
)或任意方向(-[]-
)。
以下查询没有使用索引links_weight_index
,因为它检索的是路径,而不是边:
MATCH p = ()-[e:links WHERE e.weight = 2]->() RETURN p
3. 路径模式中的起点过滤。
上面的索引user_age_index
在以下查询中有效:
MATCH p = (n:user WHERE n.age > 45)-[]-()-[]-() RETURN p
但在以下查询中无效:
MATCH p = ()-[]-(n:user WHERE n.age > 45) RETURN p
最左前缀原则
复合索引中属性的顺序非常重要:匹配到索引最左侧属性(即指定顺序里的首个属性或前几个属性)的查询会因此受益。
例如:
CREATE INDEX name_age ON NODE user (name(10),age)
MATCH (u:user WHERE u.name = "Kavi" AND u.age > 20)
使用了索引。MATCH (u:user WHERE u.name = "Kavi")
使用了索引。MATCH (u:user WHERE u.age > 20)
未使用索引。MATCH (u:user WHERE u.name = "Kavi" AND u.age > 20 AND u.grade = 7)
使用了索引,同时包含对属性grade
的过滤,但该属性没有索引。
字符串字节长度限制
使用string
或text
类型属性的索引时,需确保过滤器中使用字符串字节长度未超过该索引创建时规定的字节长度。
例如,为user
点的name
属性创建索引Username
,索引的字节长度限制为8:
CREATE INDEX Username ON NODE user (name(8))
以下查询不会使用索引Username
,因为指定的字符串Aventurine
长度超过了8字节:
MATCH (n:user {name: "Aventurine"})
RETURN n