Tôi là một trong những nhà phát triển cốt lõi của ArangoDB
và đã cố gắng tối ưu hóa truy vấn của bạn. Vì tôi không có số dataset
Tôi chỉ có thể nói về bài kiểm tra dataset
của mình và sẽ rất vui khi biết nếu bạn có thể xác thực kết quả của mình.
Đầu tiên nếu tất cả tôi đang chạy trên ArangoDB
2.7 nhưng trong trường hợp cụ thể này, tôi không mong đợi sự khác biệt lớn về hiệu suất là 2,6.
Trong số dataset
Tôi có thể thực hiện truy vấn của bạn giống như trong ~ 7 giây. Lần sửa đầu tiên: Trong tuyên bố bạn bè của bạn, bạn sử dụng includeData: true
và chỉ trả lại _id
. Với includeData: false
GRAPH_NEIGHBORS
trực tiếp trả về _id
và chúng tôi cũng có thể thoát khỏi subquery đây
LET friends = GRAPH_NEIGHBORS('graph',
@user,
{"direction": "any",
"edgeExamples": {
name: "FRIENDS_WITH"
}})
này đã nhận nó xuống ~ 1,1 giây trên máy tính của tôi. Vì vậy, tôi hy vọng rằng điều này sẽ gần với hiệu suất của Neo4J.
Tại sao điều này có tác động lớn? Trong nội bộ chúng tôi tìm thấy giá trị _id
mà không thực sự tải các tài liệu JSON. Trong truy vấn của bạn, bạn không cần bất kỳ dữ liệu nào trong số này, vì vậy chúng tôi có thể tiếp tục an toàn khi không mở nó.
Nhưng bây giờ để cải thiện thực
truy vấn của bạn đi cách "logic" và lần đầu tiên được sử dụng hàng xóm, hơn thấy người hàng xóm của họ, đếm một foaf
được tìm thấy mức độ thường xuyên và sắp xếp nó. Điều này có để xây dựng mạng foaf hoàn chỉnh trong bộ nhớ và sắp xếp nó như một toàn thể.
Bạn cũng có thể làm điều đó theo một cách khác: 1. Tìm tất cả friends
của người dùng (chỉ _ids
) 2. Tìm tất cả foaf
(tài liệu đầy đủ) 3. Đối với mỗi foaf
tất cả foaf_friends
(chỉ _ids
) 4. Tìm giao điểm của friends
và foaf_friends
và COUNT họ
truy vấn này sẽ như thế này:
LET fids = GRAPH_NEIGHBORS("graph",
@user,
{
"direction":"any",
"edgeExamples": {
"name": "FRIENDS_WITH"
}
}
)
FOR foaf IN GRAPH_NEIGHBORS("graph",
@user,
{
"minDepth": 2,
"maxDepth": 2,
"direction": "any",
"includeData": true,
"edgeExamples": {
"name": "FRIENDS_WITH"
}
}
)
LET commonIds = GRAPH_NEIGHBORS("graph",
foaf._id, {
"direction": "any",
"edgeExamples": {
"name": "FRIENDS_WITH"
}
}
)
LET common_friend_count = LENGTH(INTERSECTION(fids, commonIds))
SORT common_friend_count DESC
RETURN {user: foaf, common_friend_count: common_friend_count}
Trong biểu đồ thử nghiệm của tôi được thực hiện trong ~ 0.024 giây
Vì vậy, đây đã cho tôi một yếu tố 250 nhanh hơn thời gian thực hiện và tôi mong chờ điều này là nhanh hơn so với truy vấn hiện tại của bạn trong Neo4j, nhưng như tôi không có dataset
của bạn tôi không thể xác minh nó, nó sẽ là tốt nếu bạn có thể làm điều đó và cho tôi biết.
Một điều cuối cùng
Với edgeExamples: {name : "FRIENDS_WITH" } it is the same as with
includeData`, trong trường hợp này chúng ta phải tìm ra cạnh thực tế và nhìn vào nó. Điều này có thể tránh được nếu bạn lưu trữ các cạnh của mình trong các bộ sưu tập riêng biệt dựa trên tên của chúng. Và sau đó loại bỏ các cạnhVí dụ là tốt. Điều này sẽ tiếp tục tăng hiệu suất (đặc biệt là nếu có rất nhiều cạnh).
Future
Stay tuned cho phiên bản tiếp theo của chúng tôi, chúng tôi ngay bây giờ thêm một số chức năng hơn để AQL mà sẽ làm cho trường hợp của bạn dễ dàng hơn để truy vấn và nên cung cấp một tăng hiệu suất.
Cảm ơn! Tôi sẽ kiểm tra, xác minh và chấp nhận câu trả lời của bạn thứ hai! Chúng tôi đánh giá cao thực tế là bạn đã dành thời gian để trả lời câu hỏi của chúng tôi;) –
Trong trường hợp của chúng tôi, cải tiến đầu tiên của bạn nhanh hơn đáng kể so với phiên bản của chúng tôi. Đặc biệt là các truy vấn chậm nhất của chúng tôi được hưởng lợi từ những cải tiến của bạn. Nó thực sự mang lại kết quả AQL rất gần với phiên bản Neo4j. Đối với truy vấn thứ 2 - nó đã làm cho các truy vấn foaf tồi tệ nhất của chúng tôi nhanh hơn, nhưng các truy vấn tốt nhất một chút chậm hơn: (Dù bằng cách nào, cải tiến đầu tiên đã giúp chúng tôi rất nhiều;). –