amazon-web-services - 用于执行日期比较的简单 Neptune Gremlin 查询由于大连接而降级
问题描述
我们有一个包含客户和产品顶点的图表。对于给定的产品,我们想了解有多少在 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
这个查询非常慢,所以我查看了海王星分析器,发现了一些奇怪的东西。下面是完整的分析器输出。忽略分析器中的经过时间。这是在多次尝试同一个查询之后,所以缓存是温暖的。在野外,可能需要 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')”步骤的客户进行比较。
解决方案
海王星实际上必须解决第一个模式,
(?1=<PRODUCT_GUID>, ?5=<product-customer>, ?3, ?6)
在它解决第二个之前,
(?3, <created_on>, ?7, ?)
每个四边形模式都是由至少两个字段绑定的索引查找。因此,第一次查找使用 Neptune 中的 SPOG 索引,该索引由 Subject(ID)和 Predicate(边缘标签)绑定。这将返回一组对象(产品-客户边另一端的顶点的顶点 ID)并通过?3
变量引用它们以用于下一个模式。
在下一个模式中,这些顶点 ID ( ?3
) 与谓词(created-on 的属性键)绑定以评估日期范围的条件。因为这是一个条件评估,所以?3
必须评估集合中的每个顶点(必须读取每个顶点上的每个“created-on”属性)。
推荐阅读
- python - 将 numpy 二维数组分离为两个二维数组
- javascript - 使用 OOP 原理的带有 MySQL 包的 Node.js 类
- firebase-dynamic-links - 如何获取 Google 提供的免费域(例如 yourapp.page.link)
- arrays - 为什么这个函数会产生混乱的结果而不是计算康威的生命游戏?
- amazon-web-services - 可以通过 Hive 将数据从一个 s3 存储桶复制到另一个存储桶吗?
- postgresql-9.5 - 提取纪元和当前时间不正确
- unity3d - Unity 在生成的 C++ 中使用“-”(U+2212)作为负号
- javascript - 如何使按钮可多次点击
- c# - 如何在wpf中选择list veiw数据模板的项目?
- karate - 使用 .@ 读取 json 响应。功能文件失败