diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
index 86114bd..7be3f9a 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
@@ -92,4 +92,5 @@ public interface Query {
 
     Tree getTree(String path);
 
+    boolean isMeasureOrExplainEnabled();
 }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
index 49a3c8c..e29571d 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.api.QueryEngine;
@@ -36,12 +37,17 @@ import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
 
 /**
  * The query engine implementation.
  */
 public abstract class QueryEngineImpl implements QueryEngine {
 
+    private static final AtomicInteger ID_COUNTER = new AtomicInteger();
+    private static final String MDC_QUERY_ID = "oak.query.id";
+    private static final String MDC_QUERY_DEBUG = "oak.query.debug";
+
     static final String SQL2 = "JCR-SQL2";
     static final String SQL = "sql";
     static final String XPATH = "xpath";
@@ -164,12 +170,40 @@ public abstract class QueryEngineImpl implements QueryEngine {
             }
         }
         q.setTraversalEnabled(traversalEnabled);
-        q.prepare();
-        return q.executeQuery();
+
+        boolean mdc = false;
+        try {
+            mdc = setupMDC(q);
+            q.prepare();
+            return q.executeQuery();
+        } finally {
+            if (mdc) {
+                clearMDC();
+            }
+        }
     }
 
     protected void setTraversalEnabled(boolean traversalEnabled) {
         this.traversalEnabled = traversalEnabled;
     }
 
+    private boolean setupMDC(Query q){
+        boolean mdcEnabled = false;
+        if (q.isMeasureOrExplainEnabled()){
+            MDC.put(MDC_QUERY_DEBUG, Boolean.TRUE.toString());
+            mdcEnabled = true;
+        }
+
+        if (LOG.isDebugEnabled()){
+            MDC.put(MDC_QUERY_ID, String.valueOf(ID_COUNTER.incrementAndGet()));
+            mdcEnabled = true;
+        }
+        return mdcEnabled;
+    }
+
+    private void clearMDC() {
+        MDC.remove(MDC_QUERY_ID);
+        MDC.remove(MDC_QUERY_DEBUG);
+    }
+
 }
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
index 6dab84a..ee56bfb 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
@@ -885,6 +885,11 @@ public class QueryImpl implements Query {
         return context.getRoot().getTree(path);
     }
 
+    @Override
+    public boolean isMeasureOrExplainEnabled() {
+        return explain || measure;
+    }
+
     /**
      * Validate the path is syntactically correct, and convert it to an Oak
      * internal path (including namespace remapping if needed).
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
index c2cd04c..07e0228 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
@@ -205,7 +205,12 @@ public class UnionQueryImpl implements Query {
     public Tree getTree(String path) {
         return left.getTree(path);
     }
-    
+
+    @Override
+    public boolean isMeasureOrExplainEnabled() {
+        return explain || measure;
+    }
+
     @Override
     public int getColumnIndex(String columnName) {
         if (columns == null) {
