用于执行日期比较的简单 Neptune Gremlin 查询因大型连接而降级
Simple Neptune Gremlin query to perform date comparison degrades due to large join
我们有一个包含客户和产品顶点的图表。对于给定的产品,我们想知道有多少客户 在 DATE 之前注册并购买了该产品。我的查询看起来像
g.V('PRODUCT_GUID') // get product vertex
.out('product-customer') // get all customers who ever bought this product
.has('created_on', gte(datetime('2020-11-28T00:33:44.536Z'))) // see if the customer was created after a given date
.count() // count the results
这个查询非常慢,所以我查看了 neptune 分析器,发现了一些奇怪的东西。下面是完整的分析器输出。忽略探查器中经过的时间。这是在多次尝试同一个查询之后,所以缓存是热的。在野外,可能需要 45 秒或更长时间。
*******************************************************
Neptune Gremlin Profile
*******************************************************
Query String
==================
g.V('PRODUCT_GUID').out('product-customer').has('created_on', gte(datetime('2020-11-28T00:33:44.536Z'))).count()
Original Traversal
==================
[GraphStep(vertex,[PRODUCT_GUID]), VertexStep(OUT,[product-customer],vertex), HasStep([created_on.gte(Sat Nov 28 00:33:44 UTC 2020)]), CountGlobalStep]
Optimized Traversal
===================
Neptune steps:
[
NeptuneCountGlobalStep {
JoinGroupNode {
PatternNode[(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=30586, expectedTotalOutput=30586, indexTime=0, joinTime=14, numSearches=1, actualTotalOutput=13424}
PatternNode[(?3, <created_on>, ?7, ?) . project ask . CompareFilter(?7 >= Sat Nov 28 00:33:44 UTC 2020^^<DATETIME>) .], {estimatedCardinality=1285574, indexTime=10, joinTime=140, numSearches=13424}
}, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep], joinStats=true, optimizationTime=0, maxVarId=8, executionTime=165}
}
]
Physical Pipeline
=================
NeptuneCountGlobalStep
|-- StartOp
|-- JoinGroupOp
|-- SpoolerOp(1000)
|-- DynamicJoinOp(PatternNode[(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=30586, expectedTotalOutput=30586})
|-- SpoolerOp(1000)
|-- DynamicJoinOp(PatternNode[(?3, <created_on>, ?7, ?) . project ask . CompareFilter(?7 >= Sat Nov 28 00:33:44 UTC 2020^^<DATETIME>) .], {estimatedCardinality=1285574})
Runtime (ms)
============
Query Execution: 164.996
Traversal Metrics
=================
Step Count Traversers Time (ms) % Dur
-------------------------------------------------------------------------------------------------------------
NeptuneCountGlobalStep 1 1 164.919 100.00
>TOTAL - - 164.919 -
Predicates
==========
# of predicates: 131
Results
=======
Count: 1
Output: [22]
Index Operations
================
Query execution:
# of statement index ops: 13425
# of unique statement index ops: 13425
Duplication ratio: 1.0
# of terms materialized: 0
特别是
DynamicJoinOp(PatternNode[(?3, <created_on>, ?7, ?) . project ask . CompareFilter(?7 >= Sat Nov 28 00:33:44 UTC 2020^^) .], {estimatedCardinality=1285574})
这一行让我感到惊讶。我读这篇文章的方式是,海王星忽略了来自“.out('product-customer')”的顶点以满足“.has('created_on'...)”的要求,而是加入了在每个具有 created_on 属性的客户顶点上。
我原以为基数只是具有产品优势的客户数量,而不是每个客户。
我想知道是否有办法只运行比较来自“out('product-customer')”步骤的客户。
Neptune实际上必须解决第一个模式,
(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6)
在解决第二个问题之前,
(?3, <created_on>, ?7, ?)
每个四边形模式是由至少两个字段绑定的索引查找。因此,第一次查找使用 Neptune 中由主题(ID)和谓词(边缘标签)绑定的 SPOG 索引。这将 return 一组对象(产品-客户边缘另一端的顶点的顶点 ID)并通过下一个模式的 ?3
变量引用它们。
在下一个模式中,这些顶点 ID (?3
) 与谓词 (属性 key of created-on) 绑定以评估日期范围的条件。因为这是条件评估,所以必须评估 ?3
集合中的每个顶点(必须读取每个顶点上的每个 'created-on' 属性)。
我们有一个包含客户和产品顶点的图表。对于给定的产品,我们想知道有多少客户 在 DATE 之前注册并购买了该产品。我的查询看起来像
g.V('PRODUCT_GUID') // get product vertex
.out('product-customer') // get all customers who ever bought this product
.has('created_on', gte(datetime('2020-11-28T00:33:44.536Z'))) // see if the customer was created after a given date
.count() // count the results
这个查询非常慢,所以我查看了 neptune 分析器,发现了一些奇怪的东西。下面是完整的分析器输出。忽略探查器中经过的时间。这是在多次尝试同一个查询之后,所以缓存是热的。在野外,可能需要 45 秒或更长时间。
*******************************************************
Neptune Gremlin Profile
*******************************************************
Query String
==================
g.V('PRODUCT_GUID').out('product-customer').has('created_on', gte(datetime('2020-11-28T00:33:44.536Z'))).count()
Original Traversal
==================
[GraphStep(vertex,[PRODUCT_GUID]), VertexStep(OUT,[product-customer],vertex), HasStep([created_on.gte(Sat Nov 28 00:33:44 UTC 2020)]), CountGlobalStep]
Optimized Traversal
===================
Neptune steps:
[
NeptuneCountGlobalStep {
JoinGroupNode {
PatternNode[(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=30586, expectedTotalOutput=30586, indexTime=0, joinTime=14, numSearches=1, actualTotalOutput=13424}
PatternNode[(?3, <created_on>, ?7, ?) . project ask . CompareFilter(?7 >= Sat Nov 28 00:33:44 UTC 2020^^<DATETIME>) .], {estimatedCardinality=1285574, indexTime=10, joinTime=140, numSearches=13424}
}, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep], joinStats=true, optimizationTime=0, maxVarId=8, executionTime=165}
}
]
Physical Pipeline
=================
NeptuneCountGlobalStep
|-- StartOp
|-- JoinGroupOp
|-- SpoolerOp(1000)
|-- DynamicJoinOp(PatternNode[(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=30586, expectedTotalOutput=30586})
|-- SpoolerOp(1000)
|-- DynamicJoinOp(PatternNode[(?3, <created_on>, ?7, ?) . project ask . CompareFilter(?7 >= Sat Nov 28 00:33:44 UTC 2020^^<DATETIME>) .], {estimatedCardinality=1285574})
Runtime (ms)
============
Query Execution: 164.996
Traversal Metrics
=================
Step Count Traversers Time (ms) % Dur
-------------------------------------------------------------------------------------------------------------
NeptuneCountGlobalStep 1 1 164.919 100.00
>TOTAL - - 164.919 -
Predicates
==========
# of predicates: 131
Results
=======
Count: 1
Output: [22]
Index Operations
================
Query execution:
# of statement index ops: 13425
# of unique statement index ops: 13425
Duplication ratio: 1.0
# of terms materialized: 0
特别是
DynamicJoinOp(PatternNode[(?3, <created_on>, ?7, ?) . project ask . CompareFilter(?7 >= Sat Nov 28 00:33:44 UTC 2020^^) .], {estimatedCardinality=1285574})
这一行让我感到惊讶。我读这篇文章的方式是,海王星忽略了来自“.out('product-customer')”的顶点以满足“.has('created_on'...)”的要求,而是加入了在每个具有 created_on 属性的客户顶点上。
我原以为基数只是具有产品优势的客户数量,而不是每个客户。
我想知道是否有办法只运行比较来自“out('product-customer')”步骤的客户。
Neptune实际上必须解决第一个模式,
(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6)
在解决第二个问题之前,
(?3, <created_on>, ?7, ?)
每个四边形模式是由至少两个字段绑定的索引查找。因此,第一次查找使用 Neptune 中由主题(ID)和谓词(边缘标签)绑定的 SPOG 索引。这将 return 一组对象(产品-客户边缘另一端的顶点的顶点 ID)并通过下一个模式的 ?3
变量引用它们。
在下一个模式中,这些顶点 ID (?3
) 与谓词 (属性 key of created-on) 绑定以评估日期范围的条件。因为这是条件评估,所以必须评估 ?3
集合中的每个顶点(必须读取每个顶点上的每个 'created-on' 属性)。