[英]Arangodb AQL Filter NOT IN collection, very slow
我想找到沒有個人資料的用戶組。
ArangoDB 2.4.3
LENGTH(users) -> 130k
LENGTH(profiles) -> 110k
users.userId -> unique hash index
profiles.userId -> unique hash index
我制作的AQL片段比夏季中期穿越大峽谷的蝸牛要慢。
LET usersWithProfiles = ( /* This part is ok */
FOR i IN users
FOR j IN profiles
FILTER i.userId == j.userId
RETURN i
)
LET usersWithoutProfiles = ( /* This is not */
FOR i IN usersWithProfiles
FILTER i NOT IN users
RETURN i
)
RETURN LENGTH(usersWithoutProfiles)
我很確定有一種完全正確的做法,但是我很想念它。 有任何想法嗎?
編輯1 (在@dothebart的回復之后):
這是新查詢,但仍然很慢
LET userIds_usersWithProfile = (
FOR i IN users
FOR j IN profile
FILTER i.userId == j.userId
RETURN i.userId
)
LET usersWithoutProfiles = (
FOR i IN users
FILTER i.userId NOT IN userIds_usersWithProfile
RETURN i
)
RETURN LENGTH(usersWithoutProfiles)
另請注意,原始查詢的這部分非常昂貴:
LET usersWithoutProfiles = (
FOR i IN usersWithProfiles
FILTER i NOT IN users
RETURN i
)
原因是FILTER
使用users
,此時這是一個表達式,它將集合中的所有文檔構建為數組。 而不是使用它,我建議這個查詢,它將返回沒有關聯的配置文件記錄的用戶的_key
屬性:
FOR user IN users
LET profile = (
FOR profile IN profiles
FILTER profile.userId == user.userId
RETURN 1
)
FILTER LENGTH(profile) == 0
RETURN user._key
性能不佳的原因是它無法為您的操作使用索引,因為它需要對集合中的每個文檔進行全面比較。
您可以使用解釋https://www.arangodb.com/2015/02/02/arangodb-2-4-2實用程序讓arangodb告訴您查詢的費用在哪里。
您的查詢可能無法滿足您的期望。 usersWithoutProfiles將為空,因為任何具有配置文件的用戶都將在users集合中找到。 如果您想擁有users集合的其他部分,它可能看起來像這樣:
LET usersWithProfiles = ( /* This part is ok */
FOR i IN users
FOR j IN profiles
FILTER i.userId == j.userId
RETURN i
)
/* now we pick the IDs, we could have done that in your first query... */
LET userWithProfilesIds = FOR i IN userWithProfiles RETURN i.userId;
/* now filter the user list by that */
LET usersWithoutProfiles = FOR i IN users
FILTER i.userId NOT IN userWithProfileIds
RETURN i;
RETURN LENGTH(usersWithoutProfiles)
應該給你一個合適的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.