2015-02-10 41 views
6

我正在使用neo4j 2.1.7最近我正在試驗匹配查詢,搜索具有多個標籤的節點。而且我發現,通常查詢做標籤訂單效果搜索時間?

Match (p:A:B) return count(p) as number 

Match (p:B:A) return count(p) as number 

作品不同的時間,在極端情況下,當你有例如2個百萬個節點A和節點0 B. 所以做標籤命令效果搜索時間?這個未來在任何地方都有記錄嗎

回答

9

Neo4j在內部維護一個labelscan存儲 - 這基本上是一個查找,可以快速獲取所有節點上攜帶的定義標籤A

在做這樣

MATCH (n:A:B) return count(n) 

labelscanstore查詢中使用查找所有A節點,然後,如果這些節點進行標籤B以及他們過濾。如果n(A) >> n(B)它的方式更有效地做MATCH (n:B:A),而不是因爲你看到了只有少數B節點和過濾那些爲A.

您可以使用PROFILE MATCH (n:A:B) return count(n)查看查詢計劃。對於Neo4j < = 2.1.x,您將看到不同的查詢計劃,具體取決於您指定的標籤的順序。

從Neo4j 2.2開始(在撰寫本答覆時提供里程碑M03),有一個基於成本的Cypher優化器。現在Cypher知道節點統計信息,它們用於優化查詢。

作爲一個例子我使用以下語句來創建一些測試數據:

create (:A:B); 
with 1 as a foreach (x in range(0,1000000) | create (:A)); 
with 1 as a foreach (x in range(0,100) | create (:B)); 

我們現在有100個乙節點,1M甲節點和1個AB節點。在2.2兩種說法:

MATCH (n:B:A) return count(n) 
MATCH (n:A:B) return count(n) 

結果完全相同的查詢計劃(並因此在相同的執行速度):

+------------------+---------------+------+--------+-------------+---------------+ 
|   Operator | EstimatedRows | Rows | DbHits | Identifiers |   Other | 
+------------------+---------------+------+--------+-------------+---------------+ 
| EagerAggregation |    3 | 1 |  0 | count(n) |      | 
|   Filter |   12 | 1 |  12 |   n | hasLabel(n:A) | 
| NodeByLabelScan |   12 | 12 |  13 |   n |   :B | 
+------------------+---------------+------+--------+-------------+---------------+ 

由於只有少數B節點,它的便宜掃描B的和過濾器A。 Smart Cypher,是不是;-)

+1

很好的答案。隨着即將到來的成本爲基礎的規劃者,這種變化?如果速度更快,優化程序能否以其他方式執行此操作? – FrobberOfBits 2015-02-10 15:26:08

+1

它實際上是在2.2.0-M03中完成的 - 只是檢查了它。 – 2015-02-10 15:27:35

+0

在2.2.10中,標籤的順序對於密碼查詢仍然很重要。我的本地測試產生了不同數量的db命中:27509335!= 111913 – manonthemat 2016-09-07 20:39:10