提交 c30a3fb4 authored 作者: Thomas Mueller's avatar Thomas Mueller

Improve performance a bit.

上级 e3fce563
......@@ -8090,7 +8090,7 @@ MySQL
# See <code>src/test/org/h2/samples/optimizations.sql</code> for a few examples of queries that benefit from special optimizations built into the database.
@performance_1433_h3
#Cache Size and Type #データ型
#Cache Size and Type
@performance_1434_p
# By default the cache size of H2 is quite small. Consider using a larger cache size, or enable the second level soft reference cache. See also <a href="features.html#cache_settings">Cache Settings</a>.
......
......@@ -3634,7 +3634,7 @@ public class Parser {
private Call parserCall() {
Call command = new Call(session);
currentPrepared = command;
command.setValue(readExpression());
command.setExpression(readExpression());
return command;
}
......
......@@ -7,7 +7,6 @@
package org.h2.command.dml;
import java.sql.ResultSet;
import java.util.ArrayList;
import org.h2.command.Prepared;
import org.h2.engine.Session;
import org.h2.expression.Expression;
......@@ -16,7 +15,6 @@ import org.h2.expression.ExpressionVisitor;
import org.h2.result.LocalResult;
import org.h2.result.ResultInterface;
import org.h2.table.Column;
import org.h2.util.New;
import org.h2.value.Value;
import org.h2.value.ValueArray;
import org.h2.value.ValueResultSet;
......@@ -27,8 +25,9 @@ import org.h2.value.ValueResultSet;
*/
public class Call extends Prepared {
private Expression value;
private ArrayList<Expression> expressions;
private Expression expression;
private Expression[] expressions;
public Call(Session session) {
super(session);
......@@ -41,7 +40,7 @@ public class Call extends Prepared {
}
public int update() {
Value v = value.getValue(session);
Value v = expression.getValue(session);
int type = v.getType();
switch(type) {
case Value.RESULT_SET:
......@@ -59,17 +58,17 @@ public class Call extends Prepared {
public ResultInterface query(int maxrows) {
setCurrentRowNumber(1);
Value v = value.getValue(session);
Value v = expression.getValue(session);
if (v.getType() == Value.RESULT_SET) {
ResultSet rs = ((ValueResultSet) v).getResultSet();
return LocalResult.read(session, rs, maxrows);
} else if (v.getType() == Value.ARRAY) {
Value[] list = ((ValueArray) v).getList();
ArrayList<Expression> expr = New.arrayList();
Expression[] expr = new Expression[list.length];
for (int i = 0; i < list.length; i++) {
Value e = list[i];
Column col = new Column("C" + (i + 1), e.getType(), e.getPrecision(), e.getScale(), e.getDisplaySize());
expr.add(new ExpressionColumn(session.getDatabase(), col));
expr[i] = new ExpressionColumn(session.getDatabase(), col);
}
LocalResult result = new LocalResult(session, expr, list.length);
result.addRow(list);
......@@ -85,13 +84,12 @@ public class Call extends Prepared {
}
public void prepare() {
value = value.optimize(session);
expressions = New.arrayList();
expressions.add(value);
expression = expression.optimize(session);
expressions = new Expression[] { expression };
}
public void setValue(Expression expression) {
value = expression;
public void setExpression(Expression expression) {
this.expression = expression;
}
public boolean isQuery() {
......@@ -103,7 +101,7 @@ public class Call extends Prepared {
}
public boolean isReadOnly() {
return value.isEverything(ExpressionVisitor.READONLY);
return expression.isEverything(ExpressionVisitor.READONLY);
}
......
......@@ -243,13 +243,14 @@ public abstract class Query extends Prepared {
}
/**
* Init the order by list.
* Initialize the order by list. This call may extend the expressions list.
*
* @param expressions the select list expressions
* @param expressionSQL the select list SQL snippets
* @param orderList the order by list
* @param visible the number of visible columns in the select list
* @param mustBeInResult all order by expressions must be in the select list
* @return the new list (expressions may be added)
*/
void initOrder(ArrayList<Expression> expressions, ArrayList<String> expressionSQL, ArrayList<SelectOrderBy> orderList, int visible,
boolean mustBeInResult) {
......
......@@ -61,6 +61,7 @@ public class Select extends Query {
private ArrayList<TableFilter> filters = New.arrayList();
private ArrayList<TableFilter> topFilters = New.arrayList();
private ArrayList<Expression> expressions;
private Expression[] expressionArray;
private Expression having;
private Expression condition;
private int visibleColumnCount, distinctColumnCount;
......@@ -514,7 +515,7 @@ public class Select extends Query {
}
public ResultInterface queryMeta() {
LocalResult result = new LocalResult(session, expressions, visibleColumnCount);
LocalResult result = new LocalResult(session, expressionArray, visibleColumnCount);
result.done();
return result;
}
......@@ -530,7 +531,7 @@ public class Select extends Query {
}
}
int columnCount = expressions.size();
LocalResult result = new LocalResult(session, expressions, visibleColumnCount);
LocalResult result = new LocalResult(session, expressionArray, visibleColumnCount);
if (!sortUsingIndex) {
result.setSortOrder(sort);
}
......@@ -770,6 +771,8 @@ public class Select extends Query {
isGroupSortedQuery = true;
}
}
expressionArray = new Expression[expressions.size()];
expressions.toArray(expressionArray);
isPrepared = true;
}
......
......@@ -57,6 +57,7 @@ public class SelectUnion extends Query {
private int unionType;
private Query left, right;
private ArrayList<Expression> expressions;
private Expression[] expressionArray;
private ArrayList<SelectOrderBy> orderList;
private SortOrder sort;
private boolean distinct;
......@@ -93,9 +94,8 @@ public class SelectUnion extends Query {
}
public ResultInterface queryMeta() {
ArrayList<Expression> leftExpressions = left.getExpressions();
int columnCount = left.getColumnCount();
LocalResult result = new LocalResult(session, leftExpressions, columnCount);
LocalResult result = new LocalResult(session, expressionArray, columnCount);
result.done();
return result;
}
......@@ -108,7 +108,7 @@ public class SelectUnion extends Query {
limitExpr = ValueExpression.get(ValueInt.get(maxrows));
}
int columnCount = left.getColumnCount();
LocalResult result = new LocalResult(session, expressions, columnCount);
LocalResult result = new LocalResult(session, expressionArray, columnCount);
result.setSortOrder(sort);
if (distinct) {
left.setDistinct(true);
......@@ -156,7 +156,7 @@ public class SelectUnion extends Query {
break;
}
case INTERSECT: {
LocalResult temp = new LocalResult(session, expressions, columnCount);
LocalResult temp = new LocalResult(session, expressionArray, columnCount);
temp.setDistinct();
while (l.next()) {
temp.addRow(convert(l.currentRow(), columnCount));
......@@ -235,6 +235,8 @@ public class SelectUnion extends Query {
sort = prepareOrder(orderList, expressions.size());
orderList = null;
}
expressionArray = new Expression[expressions.size()];
expressions.toArray(expressionArray);
}
public double getCost() {
......
......@@ -269,7 +269,7 @@ public abstract class PageBtree extends Page {
if (changeCount >= index.getPageStore().getChangeCount()) {
return false;
}
return super.canRemove();
return true;
}
}
......@@ -228,7 +228,7 @@ abstract class PageData extends Page {
if (changeCount >= index.getPageStore().getChangeCount()) {
return false;
}
return super.canRemove();
return true;
}
}
......@@ -255,7 +255,7 @@ public class PageDataOverflow extends Page {
}
public boolean canRemove() {
return super.canRemove();
return true;
}
}
......@@ -73,17 +73,6 @@ public class LocalResult implements ResultInterface {
this.expressions = expressions;
}
/**
* Construct a local result object.
*
* @param session the session
* @param expressionList the expression list
* @param visibleColumnCount the number of visible columns
*/
public LocalResult(Session session, ArrayList<Expression> expressionList, int visibleColumnCount) {
this(session, getList(expressionList), visibleColumnCount);
}
/**
* Construct a local result set by reading all data from a regular result set.
*
......@@ -94,8 +83,8 @@ public class LocalResult implements ResultInterface {
*/
public static LocalResult read(Session session, ResultSet rs, int maxrows) {
try {
ArrayList<Expression> cols = getExpressionColumns(session, rs);
int columnCount = cols.size();
Expression[] cols = getExpressionColumns(session, rs);
int columnCount = cols.length;
LocalResult result = new LocalResult(session, cols, columnCount);
for (int i = 0; (maxrows == 0 || i < maxrows) && rs.next(); i++) {
Value[] list = new Value[columnCount];
......@@ -112,10 +101,10 @@ public class LocalResult implements ResultInterface {
}
}
private static ArrayList<Expression> getExpressionColumns(Session session, ResultSet rs) throws SQLException {
private static Expression[] getExpressionColumns(Session session, ResultSet rs) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
ArrayList<Expression> cols = New.arrayList(columnCount);
Expression[] expressions = new Expression[columnCount];
Database db = session == null ? null : session.getDatabase();
for (int i = 0; i < columnCount; i++) {
String name = meta.getColumnLabel(i + 1);
......@@ -125,9 +114,9 @@ public class LocalResult implements ResultInterface {
int displaySize = meta.getColumnDisplaySize(i + 1);
Column col = new Column(name, type, precision, scale, displaySize);
Expression expr = new ExpressionColumn(db, col);
cols.add(expr);
expressions[i] = expr;
}
return cols;
return expressions;
}
/**
......@@ -160,12 +149,6 @@ public class LocalResult implements ResultInterface {
return copy;
}
private static Expression[] getList(ArrayList<Expression> expressionList) {
Expression[] expressions = new Expression[expressionList.size()];
expressionList.toArray(expressions);
return expressions;
}
/**
* Set the sort order.
*
......
......@@ -83,13 +83,6 @@ public abstract class Page extends CacheObject {
*/
public abstract void moveTo(Session session, int newPos);
public boolean canRemove() {
if (isChanged()) {
return false;
}
return true;
}
/**
* Write the page.
*/
......
......@@ -16,8 +16,10 @@ import org.h2.engine.Constants;
*/
public class Profiler implements Runnable {
private static final int MAX_ELEMENTS = 1000;
private int interval = 50;
private int depth = 16;
public int interval = 50;
public int depth = 16;
private String[] ignoreLines = StringUtils.arraySplit("", ',', true);
private String[] ignoreThreads = StringUtils.arraySplit(
"java.lang.Thread.dumpThreads," +
......@@ -182,20 +184,4 @@ public class Profiler implements Runnable {
return buff.toString();
}
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
}
......@@ -138,6 +138,7 @@ import org.h2.test.utils.OutputCatcher;
import org.h2.test.utils.SelfDestructor;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Server;
import org.h2.util.Profiler;
import org.h2.util.Utils;
import org.h2.util.StringUtils;
......@@ -292,7 +293,8 @@ java org.h2.test.TestAll timer
/*
test recovery of large pages and transaction log
test recovery with 'trace' mode (btree data)
test recovery with 'trace' mode (many secondary indexes, small data rows)
improve Row.getMemorySize
maybe remove ValueHashMap
rename Page* classes
move classes to the right packages
......@@ -352,8 +354,14 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new TestTimer().runTest(test);
}
} else {
test.runTests();
// test.runTests();
Profiler prof = new Profiler();
prof.depth = 10;
prof.interval = 1;
prof.startCollecting();
TestPerformance.main("-init", "-db", "1");
prof.stopCollecting();
System.out.println(prof.getTop(2));
// Recover.execute("data", null);
// RunScript.execute("jdbc:h2:data/test2",
// "sa1", "sa1", "data/test.h2.sql", null, false);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论