2017-08-17 63 views
2

我有這樣的查詢我的應用程序的一個關鍵組成部分:爲什麼這兩個看似相同的Cypher查詢在速度上差別如此之大?

MATCH (group:GroupType) 
WHERE group.Name = "String" 
MATCH (node:NodeType) 
WHERE (node)-[:MEMBER_OF]->(group) 
RETURN node 

上有:GroupType(Name)

指數在此查詢使用近100萬的數據庫訪問大約10,000個元素的數據庫。下面是該查詢的PROFILE

Slow Query Profile

然而,其執行相同的搜索查詢的該輕微的變化要快得多:

MATCH (group:GroupType) 
WHERE group.Name = "String" 
MATCH (node:NodeType)-[:MEMBER_OF]->(group) 
RETURN node 

唯一的區別是所述node:NodeType匹配,並且關係匹配合併爲一個MATCH而不是MATCH ... WHERE。此查詢使用先前查詢的數據庫命中1/70和快10倍以上,儘管執行相同的搜索:

Good Query Profile

我想暗號處理MATCH ... WHERE語句作爲單個搜索表達式,因此兩個查詢應編譯爲相同的操作,但這兩個查詢似乎執行的操作大不相同。爲什麼是這樣?

回答

2

我想先說這不是Cypher問題。 Cypher描述了你想要的,而不是如何得到它,所以這個查詢的性能在Neo4J 3.1.1和Neo4J 3.2.3之間會非常大。

由於執行Cypher的人是決定如何執行此操作的人,所以真正的問題是「爲什麼Neo4J Cypher計劃員不會將這些視爲相同?「

理想的情況下,這兩個Cyphers的應相當於

MATCH (node:NodeType)-[:MEMBER_OF]->(group:GroupType{name:"String"}) 
RETURN node 

,因爲他們都應該產生相同的結果。

在現實中,有很多細微差別與動態解析查詢有很多「等同」的表達,但在上下文中的微妙變化可以改變這種對等,說如果你做了這個調整

MATCH (group:GroupType) 
WHERE group.Name = "String" 
MATCH (node:NodeType) 
WHERE (node)-[:MEMBER_OF]->(group) OR SIZE(group.members) = 1 
RETURN node 

現在兩個q ueries在結果上幾乎沒有任何相似之處。爲了進行擴展,查詢計劃人員必須做出決策捷徑,儘快提出一個有效的計劃。

在排序上,性能取決於你所投擲的服務器在運行的是什麼,因爲爲語言提供一個可操作的查找策略,可以讓你詢問任何事情/一切都很困難!

相關閱讀

+0

因此,如果查詢執行速度比它應該慢,我們應該嘗試通過試驗和錯誤的變化,直到我們到達在我們的Neo4j版本上足夠高效的查詢? – slbelden

+1

@slbelden是的。我還建議在查詢中添加'CYPHER '以確保接收它的Neo4j與您正在使用的語法兼容。 (安全事物)大量使用Profile分析需要經常運行的查詢。 – Tezra

+0

作爲一個方面說明,我想補充一點,我只是通過升級我使用的Neo4J版本來改進我的一些Cyphers的一個數量級。 (根本沒有任何密碼變化......我使用'(a) - [* .. 10] - >(b)'通常用於追蹤事物的方式) – Tezra

0

MATCH ... WHERE <pattern>MATCH <pattern>不一樣。

第一個查詢執行匹配,然後使用該模式作爲篩選器執行所有構建的行。

您可以在查詢計劃中看到發生的事情是您的第一個匹配結果與所有NodeType節點之間的笛卡爾積。然後,對於笛卡爾積的每一行,WHERE檢查該行上的:GroupType節點是否通過給定模式(這是Expand(Into)操作)連接到該行上的:NodeType節點。

第二個查詢相比之下,擴展了以前匹配的group節點的模式,因此從擴展中考慮的節點數量少得多,幾乎立即相關,只需要最終過濾器來確保這些節點是: NodeType節點。

編輯

由於Tezra指出,Cypher支架由具有定義你想要什麼,而不是如何得到它,因爲操作「如何」是策劃人的工作。在當前版本的Neo4j(3.2.3)中,我的解釋是,規劃人員對每個查詢進行不同的解釋併爲每個查詢生成不同的計劃,但隨着Cypher的發展和規劃人員的改進,這可能會有所變化。

在這些情況下,您應該對查詢運行PROFILE並進行相應的調整。

+0

所以[官方Neo4j的文檔,在此聲明】(https://neo4j.com/docs/developer-manual/current/cypher/clause/where /#where-introduction)不正確? 「另一方面,對於MATCH和OPTIONAL MATCH,WHERE爲所描述的模式添加了約束條件,匹配完成後不應將其視爲過濾器。」 – slbelden

+0

這是一個有點危險的解釋。雖然語法在技術上意味着不同的事情,但Cypher描述了最終結果,而不是如何得到它。 Cyphers都可以放棄使用相同的計劃,因爲它們都檢索相同的數據。 – Tezra

+1

@Tezra夠公平的,我已經編輯了我的答案。 – InverseFalcon

相關問題