Cypher 2不使用带有OR运算符的模式索引

时间:2015-02-26 15:24:36

标签: neo4j cypher

给出Neo4j 2.1.7的以下图表:

CREATE 
(:Application {Name: "Test Application", Aliases: ["Test", "App", "TestProject"]}),
(:Application {Name: "Another Application", Aliases: ["A-App", "XYZ", "XYProject"]}),
(:Application {Name: "Database X", Aliases: ["DB-App", "DB", "DB-Project"]}),
(:System {Name: "Server1", Application: "TestProject"}),
(:System {Name: "Server2", Application: "Test Application"}),
(:System {Name: "Server3", Application: "another App"}),
(:System {Name: "Server4", Application: "Some Database"}),
(:System {Name: "Server5", Application: "App"}),
(:System {Name: "Server6", Application: "App XY"}),
(:System {Name: "Server7", Application: "App DB"}),
(:System {Name: "Server8", Application: "Test"}),
(:System {Name: "Server9", Application: "TestProject"}),
(:System {Name: "Server10", Application: "test"}),
(:System {Name: "Server11", Application: "App XY"});

CREATE INDEX ON :Application(Name);
CREATE INDEX ON :Application(Aliases);

CREATE INDEX ON :System(Application);

以下查询使用架构索引:

PROFILE 
MATCH (a:Application { Name: "Test Application" })
MATCH (s:System)
WHERE s.Application = a.Name
RETURN a,s;

neo4j-sh (?)$ PROFILE  MATCH (a:Application { Name: "Test Application" }) MATCH (s:System) WHERE s.Application = a.Name RETURN a,s;
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | a                                                                     | s                                                      |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[4]{Name:"Server2",Application:"Test Application"} |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 1 row
==>
==> SchemaIndex(0)
==>   |
==>   +SchemaIndex(1)
==>
==> +----------------+------+--------+-------------+-------------------------------------------+
==> |       Operator | Rows | DbHits | Identifiers |                                     Other |
==> +----------------+------+--------+-------------+-------------------------------------------+
==> | SchemaIndex(0) |    1 |      4 |        s, s | Property(a,Name(0)); :System(Application) |
==> | SchemaIndex(1) |    1 |      2 |        a, a |       {  AUTOSTRING0}; :Application(Name) |
==> +----------------+------+--------+-------------+-------------------------------------------+
==>
==> Total database accesses: 6

-

PROFILE 
MATCH (a:Application { Name: "Test Application" })
MATCH (s:System)
WHERE s.Application IN a.Aliases
RETURN a,s;

neo4j-sh (?)$ PROFILE  MATCH (a:Application { Name: "Test Application" }) MATCH (s:System) WHERE s.Application IN a.Aliases RETURN a,s;
==> +----------------------------------------------------------------------------------------------------------------------------+
==> | a                                                                     | s                                                  |
==> +----------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[10]{Name:"Server8",Application:"Test"}        |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[7]{Name:"Server5",Application:"App"}          |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[3]{Name:"Server1",Application:"TestProject"}  |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[11]{Name:"Server9",Application:"TestProject"} |
==> +----------------------------------------------------------------------------------------------------------------------------+
==> 4 rows
==>
==> SchemaIndex(0)
==>   |
==>   +SchemaIndex(1)
==>
==> +----------------+------+--------+-------------+----------------------------------------------+
==> |       Operator | Rows | DbHits | Identifiers |                                        Other |
==> +----------------+------+--------+-------------+----------------------------------------------+
==> | SchemaIndex(0) |    4 |      9 |        s, s | Property(a,Aliases(1)); :System(Application) |
==> | SchemaIndex(1) |    1 |      2 |        a, a |          {  AUTOSTRING0}; :Application(Name) |
==> +----------------+------+--------+-------------+----------------------------------------------+
==>
==> Total database accesses: 11

与OR运算符结合使用时不是:

PROFILE 
MATCH (a:Application { Name: "Test Application"})
MATCH (s:System)
WHERE s.Application = a.Name OR s.Application IN a.Aliases
RETURN a,s;

neo4j-sh (?)$ PROFILE  MATCH (a:Application { Name: "Test Application"}) MATCH (s:System) WHERE s.Application = a.Name OR s.Application IN a.Aliases RETURN a,s;
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | a                                                                     | s                                                      |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[3]{Name:"Server1",Application:"TestProject"}      |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[4]{Name:"Server2",Application:"Test Application"} |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[7]{Name:"Server5",Application:"App"}              |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[10]{Name:"Server8",Application:"Test"}            |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[11]{Name:"Server9",Application:"TestProject"}     |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 5 rows
==> 
==> Filter
==>   |
==>   +NodeByLabel
==>     |
==>     +SchemaIndex
==> 
==> +-------------+------+--------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
==> |    Operator | Rows | DbHits | Identifiers |                                                                                                                                             Other |
==> +-------------+------+--------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
==> |      Filter |    5 |    126 |             | (Property(s,Application(2)) == Property(a,Name(0)) OR any(-_-INNER-_- in Property(a,Aliases(1)) where Property(s,Application(2)) == -_-INNER-_-)) |
==> | NodeByLabel |   11 |     12 |        s, s |                                                                                                                                           :System |
==> | SchemaIndex |    1 |      2 |        a, a |                                                                                                               {  AUTOSTRING0}; :Application(Name) |
==> +-------------+------+--------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
==> 
==> Total database accesses: 140

但是这个有效吗?

PROFILE 
MATCH (a:Application { Name: "Test Application"})
MATCH (s:System)
WHERE s.Application IN (a.Aliases + a.Name)
RETURN a,s;

neo4j-sh (?)$ PROFILE  MATCH (a:Application { Name: "Test Application"}) MATCH (s:System) WHERE s.Application IN (a.Aliases + a.Name) RETURN a,s;
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | a                                                                     | s                                                      |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[10]{Name:"Server8",Application:"Test"}            |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[7]{Name:"Server5",Application:"App"}              |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[3]{Name:"Server1",Application:"TestProject"}      |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[11]{Name:"Server9",Application:"TestProject"}     |
==> | Node[0]{Name:"Test Application",Aliases:["Test","App","TestProject"]} | Node[4]{Name:"Server2",Application:"Test Application"} |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 5 rows
==> 
==> SchemaIndex(0)
==>   |
==>   +SchemaIndex(1)
==> 
==> +----------------+------+--------+-------------+-----------------------------------------------------------------------+
==> |       Operator | Rows | DbHits | Identifiers |                                                                 Other |
==> +----------------+------+--------+-------------+-----------------------------------------------------------------------+
==> | SchemaIndex(0) |    5 |     13 |        s, s | Add(Property(a,Aliases(1)),Property(a,Name(0))); :System(Application) |
==> | SchemaIndex(1) |    1 |      2 |        a, a |                                   {  AUTOSTRING0}; :Application(Name) |
==> +----------------+------+--------+-------------+-----------------------------------------------------------------------+
==> 
==> Total database accesses: 15

为什么带OR运算符的查询不使用新索引?

1 个答案:

答案 0 :(得分:2)

因为重写者不够聪明,无法识别这个角落。

您已经回答了自己的问题,我也建议您这样做。

PROFILE 
MATCH (a:Application { Name: "Test Application"})
MATCH (s:System)
WHERE s.Application IN (a.Aliases + a.Name)
RETURN a,s;