2012-12-11 69 views
0

要查看使用Neo4J進行朋友關係的優勢,我在MySQL數據庫中創建了一個人員表(「人員」,20900集):在MySQL和Neo4J之間的朋友之間的朋友之間的朋友之間的比較

id  | name 
-------------- 
1  | Peter 
2  | Max 
3  | Sam 
... | ... 
20900 | Rudi 

和一個表的關係( 「友誼」,每個人有50至100個朋友):

personen_id_1 | personen_id_2 
------------------------- 
1   | 2 
1   | 3 
2   | 56 
...  | ... 
20900  | 201 

所以,有以防萬一120萬間的關係。

現在我想現在的朋友 - 的 - 朋友 - 的 - 朋友 - 的 - 朋友的人與ID = 1,所以我製作這樣的查詢:

select distinct P.name 
from Friendships f 
join Friendships f2 ON f.personen_id_2 = f2.personen_id_1 
join Friendships f3 ON f2.personen_id_2 = f3.personen_id_1 
join Friendships f4 ON f3.personen_id_2 = f4.personen_id_1 
join Persons P ON f4.personen_id_2 = P.id 
where f.personen_id_1 = 1 

查詢了角落找尋30秒爲用戶ID 1

在Neo4J我爲每個人創建一個節點(20900節點)與一個名稱屬性。所有節點連接等於MySQL中的友誼表,所以有120萬個關係。

在這裏得到相同的frinedset,我輸入精怪:

gremlin> g.v(1).outE.inV.loop(2){ it.loops <= 4 }.name.dedup.map() 

這場耗時角落找尋1分鐘。我根本沒有料到這一點!

所以我的比較正確嗎?如果是的話,如何修改這個例子來展示使用neo4j完成這個任務的優點?

+0

你使用了什麼JVM設置?你的硬件是什麼?對於數據庫來說,JVM的默認內存設置太小了。如果這是第一次運行,它將只測量您的磁盤速度來提取數據。 –

+0

我使用oracle jvm 1.6,堆大小設置爲'java -Xms 1G -Xmx 1G' – chris

回答

0

我不過於熟悉的Gremlin,但我產生類似大小的數據集(以下數據)和跑Cypher支架的等效查詢:

START person=node:user(name={name}) 
MATCH person-[:FRIEND]-()-[:FRIEND]-()-[:FRIEND]-()-[:FRIEND]-friend 
RETURN friend.name AS name 

我跑對數據集這個1000次,每次選擇一個不同的用戶作爲起點。在運行測試之前,我沒有預熱高速緩存,所以這是從一個開始。平均響應時間:33毫秒。

運行在MacBook Pro上,2.2 GHz的英特爾酷睿i7處理器,8 GB RAM,4 GB堆

以下是圖表統計:

+----------------------------------------------+ 
| user   | 20900      | 
+----------------------------------------------+ 
|    | Average | High |  Low | 
+----------------------------------------------+ 
| FRIEND          | 
+----------------------------------------------+ 
|  OUTGOING |  74 |  100 |  48 | 
|  incoming |  74 |  123 |  31 | 
+----------------------------------------------+ 

+----------------------------------------------+ 
| _UNKNOWN  | 1       | 
+----------------------------------------------+ 
|    | Average | High |  Low | 
+----------------------------------------------+ 

+----------------------------------------------+ 
| Totals          | 
+----------------------------------------------+ 
| Nodes   | 20901      | 
| Relationships | 1565787      | 
+----------------------------------------------+ 
| FRIEND   | 1565787      | 
+----------------------------------------------+ 
+0

我的規格:Corei5 2.5GHz,8GB內存,2GB Java堆大小。在增加節點和關係的memeory-io映射的RAM大小之後,例如'neostore.nodestore.db.mapped_memory = 1000M neostore.relationshipstore.db.mapped_memory = 1000M'查詢花費了30秒,仍然太長 – chris

+0

密碼查詢速度與gremlin中的一樣緩慢 – chris

+1

使用您的數據集,在深度爲4 ,每個人都可能連接到其他人。如果每個人都有100個好友,則深度4搜索將遍歷100 x 100 x 100 x 100個關係,即100,000,000次遍歷,或者100,000,000個實體訪問。在商品硬件上,Neo4j通常可以每秒傳輸1-2百萬個關係 - 即每秒處理1-2百萬個關聯。所以這些數字加起來。如果這是一個真正的領域,我們可能只需要深度4的前100或1000人:如果您迭代結果100次,則會得到低ms響應。 – Ian

1

如果你知道你正在做的4個迴路,做這樣的:

g.v(1).out.out.out.out.name.dedup.map 

中有小鬼一個已知的語義臭蟲環()將變成一個廣度優先查詢。 https://github.com/tinkerpop/pipes/issues/25

此外,如果你不需要,不要做outE.inV。相當於是。此外,意識到你正在做4步搜索,這是一個巨大的計算(組合爆炸)。這是圖表數據庫不擅長的。您需要查看像Faunus這樣的批量分析框架 - http://thinkaurelius.github.com/faunus/。出於某個原因,請參閱http://thinkaurelius.com/2012/04/21/loopy-lattices/

圖形數據庫針對本地遍歷進行了優化,通過4個步驟,您觸及(很可能)您的整個數據集並使用數據庫訪問的「get get get」樣式,但效率不高。

HTH, Marko。

+0

沒關係,但我認爲這應該是更高效的比同樣的szenario在MySQL? – chris

相關問題