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 2015/09/23 15:21:14 UTC
svn commit: r1704844 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ oak-core/sr...
Author: thomasm
Date: Wed Sep 23 13:21:13 2015
New Revision: 1704844
URL: http://svn.apache.org/viewvc?rev=1704844&view=rev
Log:
OAK-2852 Query engine: if counter index is not available, cost of traversing is too low
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/NodeCounter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/NodeCounter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/NodeCounter.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/NodeCounter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/NodeCounter.java Wed Sep 23 13:21:13 2015
@@ -102,12 +102,12 @@ public class NodeCounter implements Node
// check in the counter index (if it exists)
s = child(root,
IndexConstants.INDEX_DEFINITIONS_NAME,
- "counter",
- NodeCounterEditor.DATA_NODE_NAME);
- if (s == null) {
+ "counter");
+ if (s == null || !s.exists()) {
// no index
return -1;
}
+ s = child(s, NodeCounterEditor.DATA_NODE_NAME);
s = child(s, PathUtils.elements(path));
if (s == null || !s.exists()) {
// we have an index, but no data
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java Wed Sep 23 13:21:13 2015
@@ -100,6 +100,13 @@ public interface Query {
String getPlan();
/**
+ * Get the index cost. The query must already be prepared.
+ *
+ * @return the index cost
+ */
+ String getIndexCost();
+
+ /**
* Get the estimated cost.
*
* @return the estimated cost
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java Wed Sep 23 13:21:13 2015
@@ -466,6 +466,9 @@ public class QueryImpl implements Query
prepare();
if (explain) {
String plan = getPlan();
+ if (measure) {
+ plan += " cost: { " + getIndexCost() + " }";
+ }
columns = new ColumnImpl[] { new ColumnImpl("explain", "plan", "plan")};
ResultRowImpl r = new ResultRowImpl(this,
Tree.EMPTY_ARRAY,
@@ -573,6 +576,11 @@ public class QueryImpl implements Query
}
@Override
+ public String getIndexCost() {
+ return source.getIndexCost(context.getBaseState());
+ }
+
+ @Override
public double getEstimatedCost() {
return estimatedCost;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java Wed Sep 23 13:21:13 2015
@@ -140,7 +140,8 @@ public class SQL2Parser {
boolean explain = false, measure = false;
if (readIf("EXPLAIN")) {
explain = true;
- } else if (readIf("MEASURE")) {
+ }
+ if (readIf("MEASURE")) {
measure = true;
}
Query q = parseSelect();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java Wed Sep 23 13:21:13 2015
@@ -236,6 +236,17 @@ public class UnionQueryImpl implements Q
}
@Override
+ public String getIndexCost() {
+ StringBuilder buff = new StringBuilder();
+ buff.append("{ ");
+ buff.append(left.getIndexCost());
+ buff.append(", ");
+ buff.append(right.getIndexCost());
+ buff.append(" }");
+ return buff.toString();
+ }
+
+ @Override
public Tree getTree(String path) {
return left.getTree(path);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java Wed Sep 23 13:21:13 2015
@@ -46,6 +46,10 @@ abstract class AstElement {
return '[' + pathOrName + ']';
}
+ protected String quoteJson(String string) {
+ return '"' + string.replaceAll("\"", "\"\"") + '"';
+ }
+
public void setQuery(QueryImpl query) {
this.query = query;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java Wed Sep 23 13:21:13 2015
@@ -110,6 +110,18 @@ public class JoinImpl extends SourceImpl
}
@Override
+ public String getIndexCost(NodeState rootState) {
+ StringBuilder buff = new StringBuilder();
+ buff.append(toString());
+ buff.append("{ ");
+ buff.append(left.getIndexCost(rootState));
+ buff.append(", ");
+ buff.append(right.getIndexCost(rootState));
+ buff.append(" }");
+ return buff.toString();
+ }
+
+ @Override
public String toString() {
return left + " " + joinType +
" " + right + " on " + joinCondition;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Wed Sep 23 13:21:13 2015
@@ -352,6 +352,25 @@ public class SelectorImpl extends Source
return buff.toString();
}
+ @Override
+ public String getIndexCost(NodeState rootState) {
+ StringBuilder buff = new StringBuilder();
+ buff.append(quoteJson(selectorName)).append(": ");
+ QueryIndex index = getIndex();
+ if (index != null) {
+ if (index instanceof AdvancedQueryIndex) {
+ IndexPlan p = plan.getIndexPlan();
+ buff.append("{ perEntry: ").append(p.getCostPerEntry());
+ buff.append(", perExecution: ").append(p.getCostPerExecution());
+ buff.append(", count: ").append(p.getEstimatedEntryCount());
+ buff.append(" }");
+ } else {
+ buff.append(index.getCost(createFilter(true), rootState));
+ }
+ }
+ return buff.toString();
+ }
+
/**
* Create the filter condition for planning or execution.
*
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java Wed Sep 23 13:21:13 2015
@@ -86,6 +86,14 @@ public abstract class SourceImpl extends
public abstract String getPlan(NodeState rootState);
/**
+ * Get the index cost as a JSON string.
+ *
+ * @param rootState the root
+ * @return the cost
+ */
+ public abstract String getIndexCost(NodeState rootState);
+
+ /**
* Prepare executing the query (recursively). This will 'wire' the
* selectors with the join constraints, and decide which index to use.
*
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/package-info.java Wed Sep 23 13:21:13 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("2.2")
+@Version("2.3")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.query;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/Statement.java Wed Sep 23 13:21:13 2015
@@ -118,7 +118,8 @@ public class Statement {
// explain | measure ...
if (explain) {
buff.append("explain ");
- } else if (measure) {
+ }
+ if (measure) {
buff.append("measure ");
}
@@ -250,9 +251,10 @@ public class Statement {
public String toString() {
StringBuilder buff = new StringBuilder();
// explain | measure ...
- if (this.explain) {
+ if (explain) {
buff.append("explain ");
- } else if (measure) {
+ }
+ if (measure) {
buff.append("measure ");
}
buff.append(s1).append(" union ").append(s2);
Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java?rev=1704844&r1=1704843&r2=1704844&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java Wed Sep 23 13:21:13 2015
@@ -54,6 +54,9 @@ import org.apache.jackrabbit.api.securit
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.apache.jackrabbit.oak.commons.json.JsonObject;
+import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
+import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest;
import org.apache.jackrabbit.oak.jcr.NodeStoreFixture;
import org.junit.Ignore;
@@ -801,5 +804,38 @@ public class QueryTest extends AbstractR
assertFalse(ni.hasNext());
session.logout();
}
+
+ @Test
+ public void approxCount() throws Exception {
+ Session session = createAdminSession();
+ double c = getCost(session, "//*[@x=1]");
+ // *with* the counter index, the estimated cost to traverse is low
+ assertTrue("cost: " + c, c > 0 && c < 100000);
+
+ // *without* the counter index, the estimated cost to traverse is high
+ session.getNode("/oak:index/counter").remove();
+ session.save();
+ double c2 = getCost(session, "//*[@x=1]");
+ assertTrue("cost: " + c2, c2 > 1000000);
+
+ session.logout();
+ }
+
+ private static double getCost(Session session, String xpath) throws RepositoryException {
+ QueryManager qm = session.getWorkspace().getQueryManager();
+ QueryResult qr = qm.createQuery("explain measure " + xpath, "xpath").execute();
+ Row r = qr.getRows().nextRow();
+ String plan = r.getValue("plan").getString();
+ String cost = plan.substring(plan.lastIndexOf('{'));
+ JsonObject json = parseJson(cost);
+ double c = Double.parseDouble(json.getProperties().get("a"));
+ return c;
+ }
+
+ private static JsonObject parseJson(String json) {
+ JsopTokenizer t = new JsopTokenizer(json);
+ t.read('{');
+ return JsonObject.create(t);
+ }
}
Re: svn commit: r1704844 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/ oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/
oak-cor...
Posted by Chetan Mehrotra <ch...@gmail.com>.
On Thu, Sep 24, 2015 at 1:56 PM, Thomas Mueller <mu...@adobe.com> wrote:
> what about getIndexCostInfo
+1
Chetan Mehrotra
Re: svn commit: r1704844 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ oak-cor...
Posted by Thomas Mueller <mu...@adobe.com>.
Hi,
Yes, makes sense... what about getIndexCostInfo?
Regards,
Thomas
On 24/09/15 07:41, "Chetan Mehrotra" <ch...@gmail.com> wrote:
>Hi Thomas,
>
>On Wed, Sep 23, 2015 at 6:51 PM, <th...@apache.org> wrote:
>> /**
>> + * Get the index cost. The query must already be prepared.
>> + *
>> + * @return the index cost
>> + */
>> + String getIndexCost();
>
>Should this be returning string? May be we should name it better
>
>Chetan Mehrotra
Re: svn commit: r1704844 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/counter/jmx/
oak-core/src/main/java/org/apache/jackrabbit/oak/query/ oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/
oak-core/sr...
Posted by Chetan Mehrotra <ch...@gmail.com>.
Hi Thomas,
On Wed, Sep 23, 2015 at 6:51 PM, <th...@apache.org> wrote:
> /**
> + * Get the index cost. The query must already be prepared.
> + *
> + * @return the index cost
> + */
> + String getIndexCost();
Should this be returning string? May be we should name it better
Chetan Mehrotra