提交 daa175aa authored 作者: Noel Grandin's avatar Noel Grandin

#423: ANALYZE performed multiple times on one table during execution of the same statement.

use a set to keep track of the tables we need to analyze.
Perform the analysis after we have committed the main transaction, so we
don't hold table locks for any longer than necessary.
上级 e653e4e6
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #423: ANALYZE performed multiple times on one table during execution of the same statement.
</li>
<li>Issue #426: Support ANALYZE TABLE statement <li>Issue #426: Support ANALYZE TABLE statement
</li> </li>
<li>Issue #472: Support CREATE SEQUENCE ... ORDER as a NOOP for Oracle compatibility <li>Issue #472: Support CREATE SEQUENCE ... ORDER as a NOOP for Oracle compatibility
......
...@@ -13,12 +13,12 @@ import java.util.LinkedList; ...@@ -13,12 +13,12 @@ import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Command; import org.h2.command.Command;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.command.Parser; import org.h2.command.Parser;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.command.ddl.Analyze;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
import org.h2.command.dml.SetTypes; import org.h2.command.dml.SetTypes;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
...@@ -126,6 +126,11 @@ public class Session extends SessionWithState { ...@@ -126,6 +126,11 @@ public class Session extends SessionWithState {
private boolean joinBatchEnabled; private boolean joinBatchEnabled;
private boolean forceJoinOrder; private boolean forceJoinOrder;
private boolean lazyQueryExecution; private boolean lazyQueryExecution;
/**
* Tables marked for ANALYZE after the current transaction is committed.
* Prevents us calling ANALYZE repeatedly in large transactions.
*/
private HashSet<Table> tablesToAnalyze;
/** /**
* Temporary LOBs from result sets. Those are kept for some time. The * Temporary LOBs from result sets. Those are kept for some time. The
...@@ -659,6 +664,14 @@ public class Session extends SessionWithState { ...@@ -659,6 +664,14 @@ public class Session extends SessionWithState {
} }
} }
endTransaction(); endTransaction();
int rows = getDatabase().getSettings().analyzeSample / 10;
if (tablesToAnalyze != null) {
for (Table table : tablesToAnalyze) {
Analyze.analyzeTable(this, table, rows, false);
}
}
tablesToAnalyze = null;
} }
private void removeTemporaryLobs(boolean onTimeout) { private void removeTemporaryLobs(boolean onTimeout) {
...@@ -1682,6 +1695,13 @@ public class Session extends SessionWithState { ...@@ -1682,6 +1695,13 @@ public class Session extends SessionWithState {
return false; return false;
} }
public void markTableForAnalyze(Table table) {
if (tablesToAnalyze == null) {
tablesToAnalyze = New.hashSet();
}
tablesToAnalyze.add(table);
}
/** /**
* Represents a savepoint (a position in a transaction to where one can roll * Represents a savepoint (a position in a transaction to where one can roll
* back to). * back to).
......
...@@ -12,10 +12,8 @@ import java.util.Comparator; ...@@ -12,10 +12,8 @@ import java.util.Comparator;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.ddl.Analyze;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
import org.h2.constraint.ConstraintReferential; import org.h2.constraint.ConstraintReferential;
...@@ -738,7 +736,7 @@ public class MVTable extends TableBase { ...@@ -738,7 +736,7 @@ public class MVTable extends TableBase {
nextAnalyze = n; nextAnalyze = n;
} }
int rows = session.getDatabase().getSettings().analyzeSample / 10; int rows = session.getDatabase().getSettings().analyzeSample / 10;
Analyze.analyzeTable(session, this, rows, false); session.markTableForAnalyze(this);
} }
@Override @Override
......
...@@ -12,10 +12,8 @@ import java.util.Comparator; ...@@ -12,10 +12,8 @@ import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.ddl.Analyze;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
import org.h2.constraint.ConstraintReferential; import org.h2.constraint.ConstraintReferential;
...@@ -431,8 +429,7 @@ public class RegularTable extends TableBase { ...@@ -431,8 +429,7 @@ public class RegularTable extends TableBase {
if (n > 0) { if (n > 0) {
nextAnalyze = n; nextAnalyze = n;
} }
int rows = session.getDatabase().getSettings().analyzeSample / 10; session.markTableForAnalyze(this);
Analyze.analyzeTable(session, this, rows, false);
} }
@Override @Override
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论