2014-03-07 59 views
0

我需要將「應用程序」類型的節點與安裝應用程序的系統上創建的用戶連接起來。關係創建的查詢非常緩慢

正常情況下,「應用程序」安裝在羣集對(2個系統)上,只有默認系統爲屬性「n.System」。

「應用」具有命名模式:<prefix><number of 5 digits>,例如, yxz12345或ab23456等。

在每個系統上都創建了用戶帳戶(有時每個系統最多有100個帳戶)。它們中的一些具有類似於「應用程序」的命名模式:例如<prefix><number of 5 digits>,例如, sdjhg12345或tzrw23456等一些不是。

作爲「用戶」屬性的「應用程序」屬性可以包含在u.Name = n.User上運行的用戶,也可以使用在其前綴right(u.Name, 5) = right(n.Name, 5)之後具有相同5位數字的所有「用戶」。

所有系統都共享用戶名,因此我們只需要鏈接相同系統上的用戶。

我使用下面的查詢,以創建關係:

MATCH (n:Application {Id: 1}) 
WITH n 
MATCH (s:System)-[:ClusteredWith]-(c:System) 
WHERE s.Name = n.System 
WITH n, s, c 
MATCH (u:User) 
WHERE 
    ((u)-[:CreatedOn]->(s) OR (u)-[:CreatedOn]->(c)) 
AND 
    (u.Name = n.User OR right(u.Name, 5) = right(n.Name, 5)) 

CREATE UNIQUE (u)-[:UsedFor]->(n) 

有是8000個系統100000個用戶,並在目前的Neo4j數據庫30000個應用。

我已經上標識汽車的性能指標,名稱,用戶

這個查詢是一個非常強大的硬件(高達96 GB內存等)的極端緩慢。 我正在使用Neo4jClient版本1.0.0.646和Neo4j 2.0.1

如何快速獲取此查詢?

編輯:查詢計劃新增:

==> EmptyResult(_rows=0, _db_hits=0) 
==> UpdateGraph(commands=[{"action": "CreateUnique", "identifiers": ["u", "n", " UNNAMED305"]}], _rows=0, _db_hits=0) 
==> Eager(_rows=0, _db_hits=0) 
==>  Filter(pred="((nonEmpty(PathExpression((u)-[ UNNAMED165:CreatedOn]->(s), true)) OR nonEmpty(PathExpression((u)-[ UNNAMED196:CreatedOn]->(c), true))) AND (Property(u,Name(0)) == Property(n,User(33)) OR RightFunction(Property(u,Name(0)),Literal(5)) == RightFunction(Property(n,Name(0)),Literal(5))))", _rows=0, _db_hits=29774466) 
==>  NodeByLabel(identifier="u", _db_hits=0, _rows=4962411, label="User", identifiers=["u"], producer="NodeByLabel") 
==>   ColumnFilter(symKeys=["n", "c", "s", " UNNAMED58"], returnItemNames=["n", "s", "c"], _rows=183, _db_hits=0) 
==>   Filter(pred="(Property(s,Name(0)) == Property(n,System(36)) AND hasLabel(s:System(0)))", _rows=183, _db_hits=366) 
==>    SimplePatternMatcher(g="(c)-[' UNNAMED58']-(s)", _rows=183, _db_hits=4880) 
==>    NodeByLabel(identifier="c", _db_hits=0, _rows=2915, label="System", identifiers=["c"], producer="NodeByLabel") 
==>     Filter(pred="Property(n,Id(0)) == Literal(1)", _rows=1, _db_hits=702) 
==>     NodeByLabel(identifier="n", _db_hits=0, _rows=702, label="Application", identifiers=["n"], producer="NodeByLabel") 

這是2個系統的應用程序,但沒有匹配的用戶(目前)

+1

批量更新通常會有點慢。您可能想嘗試使用PERIODIC COMMIT語句。它最近在2.1.0.M1發佈。 – tstorms

+0

只有最初的重建數據庫是一個「批量」導入,我會試一試..但在正常運行(新應用程序並不經常),它是緩慢的,有時超時 – dna

回答

1

檔案查詢(how?)的查詢和審查執行計劃請注意以下幾點:

  1. :Application(Id)是否唯一?
  2. 比較需要多少個數據庫命中:Application(System) = :System(Name)?他們完全可以通過(:Application)-[:InstalledOn]->(:System)來避免嗎?
  3. 您是否在WITH n, s, c上綁定了重複的路徑/結果項?
    • 〜模式(s:System)-[:ClusteredWith]-(c:System)是對稱
    • 〜重複意味着查詢的其餘部分被執行多次
  4. 多少用戶匹配?索引是否被使用?這可能不是因爲WHERE子句很複雜,可能過於複雜,引擎無法重構爲精確查找。您是否可以重構它以允許初始索引查找,或者甚至更好,通過(:System)<-[:CreatedOn]-(:User)訪問用戶以避免處理所有不相關的用戶?

我的猜測是大瓶頸是用戶查找。如果在查詢中當前還有多個結果項目,則問題會複雜化。以下是猜測,但也許你可以調整它並讓它起作用。

MATCH (app:Application {Id: 1}) 
MATCH (:System {Name:app.System})-[:ClusteredWith*0..1]-(sys:System)<-[:CreatedOn]-(user) 
WHERE (user.Name = app.User OR right(user.Name, 5) = right(app.Name, 5)) 
CREATE UNIQUE (user)-[:UsedFor]->(app) 
+0

嗨,感謝您的幫助回答。我添加了當前的查詢計劃,我會在下週嘗試一下您的建議。 – dna

+1

你也可以發佈你的索引配置(在neo4j-browser中爲':schema',在neo4j-shell中爲'schema'),從執行計劃看,它看起來並不像任何索引正在被使用。 – jjaderberg

+0

你是對的: ==>沒有索引 ==> ==>沒有約束 爲什麼autoindex被啓用? – dna