提交 9a0977bd authored 作者: Thomas Mueller's avatar Thomas Mueller

EXPLAIN ANALYZE now also lists the number of pages read from the file.

上级 751020f2
...@@ -6,12 +6,16 @@ ...@@ -6,12 +6,16 @@
*/ */
package org.h2.command.dml; package org.h2.command.dml;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn; import org.h2.expression.ExpressionColumn;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.store.PageStore;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueString; import org.h2.value.ValueString;
...@@ -52,14 +56,37 @@ public class Explain extends Prepared { ...@@ -52,14 +56,37 @@ public class Explain extends Prepared {
Expression[] expressions = { expr }; Expression[] expressions = { expr };
result = new LocalResult(session, expressions, 1); result = new LocalResult(session, expressions, 1);
if (maxrows >= 0) { if (maxrows >= 0) {
String plan;
if (executeCommand) { if (executeCommand) {
PageStore store = session.getDatabase().getPageStore();
store.statisticsStart();
if (command.isQuery()) { if (command.isQuery()) {
command.query(maxrows); command.query(maxrows);
} else { } else {
command.update(); command.update();
} }
plan = command.getPlanSQL();
Map<String, Integer> statistics = store.statisticsEnd();
if (statistics != null) {
int total = 0;
for (Entry<String, Integer> e : statistics.entrySet()) {
total += e.getValue();
}
if (total > 0) {
statistics = new TreeMap<String, Integer>(statistics);
StringBuilder buff = new StringBuilder();
buff.append("total: ").append(total).append('\n');
for (Entry<String, Integer> e : statistics.entrySet()) {
int value = e.getValue();
int percent = (int) (100L * value / total);
buff.append(e.getKey()).append(": ").append(value).append(" (").append(percent).append("%)\n");
}
plan += "\n/*\n" + buff.toString() + "*/";
}
}
} else {
plan = command.getPlanSQL();
} }
String plan = command.getPlanSQL();
add(plan); add(plan);
} }
result.done(); result.done();
......
...@@ -205,6 +205,8 @@ public class PageStore implements CacheWriter { ...@@ -205,6 +205,8 @@ public class PageStore implements CacheWriter {
private long logSizeBase; private long logSizeBase;
private HashMap<String, Integer> statistics;
/** /**
* Create a new page store object. * Create a new page store object.
* *
...@@ -225,6 +227,31 @@ public class PageStore implements CacheWriter { ...@@ -225,6 +227,31 @@ public class PageStore implements CacheWriter {
systemSession = new Session(database, null, 0); systemSession = new Session(database, null, 0);
} }
/**
* Start collecting statistics.
*/
public void statisticsStart() {
statistics = New.hashMap();
}
/**
* Stop collecting statistics.
*
* @return the statistics
*/
public HashMap<String, Integer> statisticsEnd() {
HashMap<String, Integer> result = statistics;
statistics = null;
return result;
}
private void statisticsIncrement(String key) {
if (statistics != null) {
Integer old = statistics.get(key);
statistics.put(key, old == null ? 1 : old + 1);
}
}
/** /**
* Copy the next page to the output stream. * Copy the next page to the output stream.
* *
...@@ -546,6 +573,9 @@ public class PageStore implements CacheWriter { ...@@ -546,6 +573,9 @@ public class PageStore implements CacheWriter {
if (index == null) { if (index == null) {
throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
} }
if (statistics != null) {
statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
}
p = PageDataLeaf.read(index, data, pageId); p = PageDataLeaf.read(index, data, pageId);
break; break;
} }
...@@ -555,11 +585,17 @@ public class PageStore implements CacheWriter { ...@@ -555,11 +585,17 @@ public class PageStore implements CacheWriter {
if (index == null) { if (index == null) {
throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
} }
if (statistics != null) {
statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
}
p = PageDataNode.read(index, data, pageId); p = PageDataNode.read(index, data, pageId);
break; break;
} }
case Page.TYPE_DATA_OVERFLOW: { case Page.TYPE_DATA_OVERFLOW: {
p = PageDataOverflow.read(this, data, pageId); p = PageDataOverflow.read(this, data, pageId);
if (statistics != null) {
statisticsIncrement("overflow read");
}
break; break;
} }
case Page.TYPE_BTREE_LEAF: { case Page.TYPE_BTREE_LEAF: {
...@@ -568,6 +604,9 @@ public class PageStore implements CacheWriter { ...@@ -568,6 +604,9 @@ public class PageStore implements CacheWriter {
if (index == null) { if (index == null) {
throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
} }
if (statistics != null) {
statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
}
p = PageBtreeLeaf.read(index, data, pageId); p = PageBtreeLeaf.read(index, data, pageId);
break; break;
} }
...@@ -577,6 +616,9 @@ public class PageStore implements CacheWriter { ...@@ -577,6 +616,9 @@ public class PageStore implements CacheWriter {
if (index == null) { if (index == null) {
throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId); throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "index not found " + indexId);
} }
if (statistics != null) {
statisticsIncrement(index.getTable().getName() + "." + index.getName() + " read");
}
p = PageBtreeNode.read(index, data, pageId); p = PageBtreeNode.read(index, data, pageId);
break; break;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论