You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2014/06/23 11:54:03 UTC
svn commit: r1604728 - in /jackrabbit/oak/branches/1.0:
oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
Author: thomasm
Date: Mon Jun 23 09:54:02 2014
New Revision: 1604728
URL: http://svn.apache.org/r1604728
Log:
OAK-1898 Query: Incorrect cost calculation for traversal
Modified:
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java?rev=1604728&r1=1604727&r2=1604728&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java Mon Jun 23 09:54:02 2014
@@ -49,7 +49,12 @@ public class TraversingIndex implements
if (filter.isAlwaysFalse()) {
return 0;
}
- double nodeCount = 10000000;
+
+ // worst case 100 million nodes
+ double nodeCount = 100000000;
+ // worst case 100 thousand children
+ double nodeCountChildren = 100000;
+
// if the path is from a join, then the depth is not correct
// (the path might be the root node), but that's OK
String path = filter.getPath();
@@ -62,9 +67,14 @@ public class TraversingIndex implements
break;
case ALL_CHILDREN:
if (!PathUtils.denotesRoot(path)) {
- for (int depth = PathUtils.getDepth(path); depth > 0; depth--) {
- // estimate 10 child nodes per node
- nodeCount /= 10;
+ int depth = PathUtils.getDepth(path);
+ for (int i = depth; i > 0; i--) {
+ // estimate 10 child nodes per node,
+ // but higher than the cost for DIRECT_CHILDREN
+ // (about 100'000)
+ // in any case, the higher the depth of the path,
+ // the lower the cost
+ nodeCount = Math.max(nodeCountChildren * 2 - depth, nodeCount / 10);
}
}
break;
@@ -76,8 +86,10 @@ public class TraversingIndex implements
}
break;
case DIRECT_CHILDREN:
- // we expect 1 million child nodes in the worst case
- nodeCount = 1000000;
+ // estimate 100'000 children for now,
+ // to ensure an index is used if there is one
+ // TODO we need to have better estimates, see also OAK-1898
+ nodeCount = nodeCountChildren;
break;
default:
throw new IllegalArgumentException("Unknown restriction: " + restriction);
Modified: jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java?rev=1604728&r1=1604727&r2=1604728&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryPlanTest.java Mon Jun 23 09:54:02 2014
@@ -44,7 +44,40 @@ public class QueryPlanTest extends Abstr
}
@Test
- @Ignore("OAK-1155")
+ // OAK-1898
+ public void traversalVersusPropertyIndex() throws Exception {
+ Session session = getAdminSession();
+ QueryManager qm = session.getWorkspace().getQueryManager();
+ Node testRootNode = session.getRootNode().addNode("testroot");
+ Node n = testRootNode;
+ for (int i = 0; i < 20; i++) {
+ n.setProperty("depth", i + 2);
+ n = n.addNode("n", "oak:Unstructured");
+ n.addMixin("mix:referenceable");
+ }
+ session.save();
+
+ String xpath = "/jcr:root/testroot/n/n/n/n/n/n/n//*[jcr:uuid]";
+
+ Query q;
+ QueryResult result;
+ RowIterator it;
+
+ q = qm.createQuery("explain " + xpath, "xpath");
+ result = q.execute();
+ it = result.getRows();
+ assertTrue(it.hasNext());
+ String plan = it.nextRow().getValue("plan").getString();
+ System.out.println("plan: " + plan);
+ // should not use the index on "jcr:uuid"
+ assertEquals("[nt:base] as [a] /* property jcr:uuid " +
+ "where ([a].[jcr:uuid] is not null) and " +
+ "(isdescendantnode([a], [/testroot/n/n/n/n/n/n/n])) */",
+ plan);
+
+ }
+
+ @Test
public void nodeType() throws Exception {
Session session = getAdminSession();
QueryManager qm = session.getWorkspace().getQueryManager();