后续查询需要哪些索引以避免全图扫描?
Which indexes do I need for following query to avoid a full-graph scan?
以下查询应该 return 最多 limit
个标签为 REPOSITORY
的顶点,这些顶点在 minLastUpdated
之前最后更新并且不属于类型 FILE_UPLOAD
,除非设置了 NEEDS_UPDATE
标志。
g.V()
.hasLabel(VertexLabel.REPOSITORY.name())
.has(PropertyKey.INDEXED_LABEL.name(), VertexLabel.REPOSITORY.name())
.has(PropertyKey.LAST_UPDATED.name(), P.lt(minLastUpdated))
.or(__.not(__.has(PropertyKey.TYPE.name(), RepositoryType.FILE_UPLOAD.name())),
__.has(PropertyKey.NEEDS_UPDATE.name(), true))
.limit(limit);
为了避免全图扫描,我在属性 INDEXED_LABEL
、TYPE
和 NEEDS_UPDATE
上创建了以下索引,一个结合了所有这三个索引和一个混合索引的复合索引:
//By Label
mgmt.buildIndex("byIndexedLabel", Vertex.class)
.addKey(indexedLabelKey)
.buildCompositeIndex();
//By Type
mgmt.buildIndex("byType", Vertex.class)
.addKey(typeKey)
.buildCompositeIndex();
//By Needs Update
mgmt.buildIndex("byNeedsUpdate", Vertex.class)
.addKey(needsUpdateKey)
.buildCompositeIndex();
//Combination of the three
mgmt.buildIndex("byIndexedLabelTypeAndNeedsUpdate", Vertex.class)
.addKey(indexedLabelKey)
.addKey(typeKey)
.addKey(needsUpdateKey)
.buildCompositeIndex();
//Mixed Index
mgmt.buildIndex("repositoryByTypeAndLastUpdated", Vertex.class)
.addKey(indexedLabelKey, Mapping.STRING.asParameter())
.addKey(lastUpdatedKey)
.indexOnly(repositoryLabel)
.buildMixedIndex("search");
然而,在执行查询时,我收到此警告:
WARN - StandardTitanTx: Query requires iterating over all vertices [()]. For better performance, use indexes
旁注
- 顶点标签是在与索引相同的事务中定义的,这意味着所有索引都应立即可用。
PropertyKey
和VertexLabel
是我自己的enums
。
- 索引设置期间使用的键都是我之前添加的
com.thinkaurelius.titan.core.PropertyKey
的实例。
- 除
NEEDS_UPDATE
外,所有属性的数据类型均为 String
,它是 Boolean
。
环境
- 泰坦 1.0.0
- TinkerPop 3.0.1
- 弹性搜索 1.0.0
- 伯克利存储后端
感谢您提出任何建议。
只有PropertyKey.INDEXED_LABEL.name()
和PropertyKey.LAST_UPDATED.name()
相关,其他属性不能用于索引查找。也就是说,创建搜索索引是有意义的,因为 a) 您有多个属性,b) 其中一个具有范围条件:P.lt(minLastUpdated)
(没有其他索引可以回答范围查询,并且具有多个多个属性众所周知,复合索引迟早会引起麻烦)。创建涵盖两个属性的单个索引以获得最佳性能。
mgmt.buildIndex('repositoryByTypeAndLastUpdated', Vertex.class).
addKey(indexedLabelKey, Mapping.STRING.asParameter()).
addKey(lastUpdatedKey).indexOnly(repositoryLabel).buildMixedIndex("search")
更新:
INDEXED_LABEL
实际上不可索引,或者更确切地说不应被索引,因为它似乎只是存储为 属性 的顶点标签的副本。下面是一个完整的示例,它不会给您任何关于全面扫描的警告。
gremlin> graph = TitanFactory.open("conf/titan-berkeleyje-es.properties")
==>standardtitangraph[berkeleyje:/projects/aurelius/titan/conf/../db/berkeley]
gremlin> g = graph.traversal()
==>graphtraversalsource[standardtitangraph[berkeleyje:/projects/aurelius/titan/conf/../db/berkeley], standard]
gremlin> m = graph.openManagement()
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@10a0a1e
gremlin> repository = m.makeVertexLabel("repository").make()
==>repository
gremlin> lastUpdated = m.makePropertyKey("lastUpdated").dataType(Long.class).make()
==>lastUpdated
gremlin> needsUpdate = m.makePropertyKey("needsUpdate").dataType(Boolean.class).make()
==>needsUpdate
gremlin> type = m.makePropertyKey("type").dataType(String.class).make()
==>type
gremlin> m.buildIndex("repositoryByLastUpdated", Vertex.class).
gremlin> addKey(lastUpdated).indexOnly(repository).buildMixedIndex("search")
==>repositoryByLastUpdated
gremlin> m.commit()
==>null
gremlin> g.V().has("repository", "lastUpdated", lt(System.currentTimeMillis())).
gremlin> or(has("type", neq("FILE UPLOAD")), has("needsUpdate", true)).limit(10)
gremlin>
我的图表中没有数据,但会显示带有或 w/o 数据的警告。
以下查询应该 return 最多 limit
个标签为 REPOSITORY
的顶点,这些顶点在 minLastUpdated
之前最后更新并且不属于类型 FILE_UPLOAD
,除非设置了 NEEDS_UPDATE
标志。
g.V()
.hasLabel(VertexLabel.REPOSITORY.name())
.has(PropertyKey.INDEXED_LABEL.name(), VertexLabel.REPOSITORY.name())
.has(PropertyKey.LAST_UPDATED.name(), P.lt(minLastUpdated))
.or(__.not(__.has(PropertyKey.TYPE.name(), RepositoryType.FILE_UPLOAD.name())),
__.has(PropertyKey.NEEDS_UPDATE.name(), true))
.limit(limit);
为了避免全图扫描,我在属性 INDEXED_LABEL
、TYPE
和 NEEDS_UPDATE
上创建了以下索引,一个结合了所有这三个索引和一个混合索引的复合索引:
//By Label
mgmt.buildIndex("byIndexedLabel", Vertex.class)
.addKey(indexedLabelKey)
.buildCompositeIndex();
//By Type
mgmt.buildIndex("byType", Vertex.class)
.addKey(typeKey)
.buildCompositeIndex();
//By Needs Update
mgmt.buildIndex("byNeedsUpdate", Vertex.class)
.addKey(needsUpdateKey)
.buildCompositeIndex();
//Combination of the three
mgmt.buildIndex("byIndexedLabelTypeAndNeedsUpdate", Vertex.class)
.addKey(indexedLabelKey)
.addKey(typeKey)
.addKey(needsUpdateKey)
.buildCompositeIndex();
//Mixed Index
mgmt.buildIndex("repositoryByTypeAndLastUpdated", Vertex.class)
.addKey(indexedLabelKey, Mapping.STRING.asParameter())
.addKey(lastUpdatedKey)
.indexOnly(repositoryLabel)
.buildMixedIndex("search");
然而,在执行查询时,我收到此警告:
WARN - StandardTitanTx: Query requires iterating over all vertices [()]. For better performance, use indexes
旁注
- 顶点标签是在与索引相同的事务中定义的,这意味着所有索引都应立即可用。
PropertyKey
和VertexLabel
是我自己的enums
。- 索引设置期间使用的键都是我之前添加的
com.thinkaurelius.titan.core.PropertyKey
的实例。 - 除
NEEDS_UPDATE
外,所有属性的数据类型均为String
,它是Boolean
。
环境
- 泰坦 1.0.0
- TinkerPop 3.0.1
- 弹性搜索 1.0.0
- 伯克利存储后端
感谢您提出任何建议。
只有PropertyKey.INDEXED_LABEL.name()
和PropertyKey.LAST_UPDATED.name()
相关,其他属性不能用于索引查找。也就是说,创建搜索索引是有意义的,因为 a) 您有多个属性,b) 其中一个具有范围条件:P.lt(minLastUpdated)
(没有其他索引可以回答范围查询,并且具有多个多个属性众所周知,复合索引迟早会引起麻烦)。创建涵盖两个属性的单个索引以获得最佳性能。
mgmt.buildIndex('repositoryByTypeAndLastUpdated', Vertex.class).
addKey(indexedLabelKey, Mapping.STRING.asParameter()).
addKey(lastUpdatedKey).indexOnly(repositoryLabel).buildMixedIndex("search")
更新:
INDEXED_LABEL
实际上不可索引,或者更确切地说不应被索引,因为它似乎只是存储为 属性 的顶点标签的副本。下面是一个完整的示例,它不会给您任何关于全面扫描的警告。
gremlin> graph = TitanFactory.open("conf/titan-berkeleyje-es.properties")
==>standardtitangraph[berkeleyje:/projects/aurelius/titan/conf/../db/berkeley]
gremlin> g = graph.traversal()
==>graphtraversalsource[standardtitangraph[berkeleyje:/projects/aurelius/titan/conf/../db/berkeley], standard]
gremlin> m = graph.openManagement()
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@10a0a1e
gremlin> repository = m.makeVertexLabel("repository").make()
==>repository
gremlin> lastUpdated = m.makePropertyKey("lastUpdated").dataType(Long.class).make()
==>lastUpdated
gremlin> needsUpdate = m.makePropertyKey("needsUpdate").dataType(Boolean.class).make()
==>needsUpdate
gremlin> type = m.makePropertyKey("type").dataType(String.class).make()
==>type
gremlin> m.buildIndex("repositoryByLastUpdated", Vertex.class).
gremlin> addKey(lastUpdated).indexOnly(repository).buildMixedIndex("search")
==>repositoryByLastUpdated
gremlin> m.commit()
==>null
gremlin> g.V().has("repository", "lastUpdated", lt(System.currentTimeMillis())).
gremlin> or(has("type", neq("FILE UPLOAD")), has("needsUpdate", true)).limit(10)
gremlin>
我的图表中没有数据,但会显示带有或 w/o 数据的警告。