Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
1f12ebf1
提交
1f12ebf1
authored
3月 02, 2011
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Documentation.
上级
790a5ccd
全部展开
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
134 行增加
和
119 行删除
+134
-119
changelog.html
h2/src/docsrc/html/changelog.html
+2
-1
performance.html
h2/src/docsrc/html/performance.html
+116
-83
roadmap.html
h2/src/docsrc/html/roadmap.html
+11
-33
tutorial.html
h2/src/docsrc/html/tutorial.html
+5
-2
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
1f12ebf1
...
...
@@ -18,7 +18,8 @@ Change Log
<h1>
Change Log
</h1>
<h2>
Next Version (unreleased)
</h2>
<ul><li>
-
<ul><li>
Database-level connection settings could only be set in the database URL,
but not using the Properties parameter of DriverManaget.getConnection(String url, Properties info).
</li></ul>
<h2>
Version 1.3.152 Beta (2011-03-01)
</h2>
...
...
h2/src/docsrc/html/performance.html
浏览文件 @
1f12ebf1
...
...
@@ -28,10 +28,10 @@ Performance
Application Profiling
</a><br
/>
<a
href=
"#database_profiling"
>
Database Profiling
</a><br
/>
<a
href=
"#storage_and_indexes"
>
How Data is Stored and How Indexes Work
</a><br
/>
<a
href=
"#explain_plan"
>
Statement Execution Plans
</a><br
/>
<a
href=
"#storage_and_indexes"
>
How Data is Stored and How Indexes Work
</a><br
/>
<a
href=
"#fast_import"
>
Fast Database Import
</a><br
/>
...
...
@@ -611,6 +611,92 @@ following profiling data (results vary):
-- 0% 100% 0 1 0 SET TRACE_LEVEL_FILE 3;
</pre>
<h2
id=
"explain_plan"
>
Statement Execution Plans
</h2>
<p>
The SQL statement
<code>
EXPLAIN
</code>
displays the indexes and optimizations the database uses for a statement.
The following statements support
<code>
EXPLAIN
</code>
:
<code>
SELECT, UPDATE, DELETE, MERGE, INSERT
</code>
.
The following query shows that the database uses the primary key index to search for rows:
</p>
<pre>
EXPLAIN SELECT * FROM TEST WHERE ID=1;
SELECT
TEST.ID,
TEST.NAME
FROM PUBLIC.TEST
/* PUBLIC.PRIMARY_KEY_2: ID = 1 */
WHERE ID = 1
</pre>
<p>
For joins, the tables in the execution plan are sorted in the order they are processed.
The following query shows the database first processes the table
<code>
INVOICE
</code>
(using the primary key).
For each row, it will additionally check that the value of the column
<code>
AMOUNT
</code>
is larger than zero,
and for those rows the database will search in the table
<code>
CUSTOMER
</code>
(using the primary key).
The query plan contains some redundancy so it is a valid statement.
</p>
<pre>
CREATE TABLE CUSTOMER(ID IDENTITY, NAME VARCHAR);
CREATE TABLE INVOICE(ID IDENTITY,
CUSTOMER_ID INT REFERENCES CUSTOMER(ID),
AMOUNT NUMBER);
EXPLAIN SELECT I.ID, C.NAME FROM CUSTOMER C, INVOICE I
WHERE I.ID=10 AND AMOUNT>0 AND C.ID=I.CUSTOMER_ID;
SELECT
I.ID,
C.NAME
FROM PUBLIC.INVOICE I
/* PUBLIC.PRIMARY_KEY_9: ID = 10 */
/* WHERE (I.ID = 10)
AND (AMOUNT > 0)
*/
INNER JOIN PUBLIC.CUSTOMER C
/* PUBLIC.PRIMARY_KEY_5: ID = I.CUSTOMER_ID */
ON 1=1
WHERE (C.ID = I.CUSTOMER_ID)
AND ((I.ID = 10)
AND (AMOUNT > 0))
</pre>
<h3>
Displaying the Scan Count
</h3>
<p>
<code>
EXPLAIN ANALYZE
</code>
additionally shows the scanned rows per table and pages read from disk per table or index.
This will actually execute the query, unlike
<code>
EXPLAIN
</code>
which only prepares it.
The following query scanned 1000 rows, and to do that had to read 85 pages from the data area of the table.
Running the query twice will not list the pages read from disk, because they are now in the cache.
The
<code>
tableScan
</code>
means this query doesn't use an index.
</p>
<pre>
EXPLAIN ANALYZE SELECT * FROM TEST;
SELECT
TEST.ID,
TEST.NAME
FROM PUBLIC.TEST
/* PUBLIC.TEST.tableScan */
/* scanCount: 1000 */
/*
total: 85
TEST.TEST_DATA read: 85 (100%)
*/
</pre>
<h3>
Special Optimizations
</h3>
<p>
For certain queries, the database doesn't need to read all rows, or doesn't need to sort the result even if
<code>
ORDER BY
</code>
is used.
</p><p>
For queries of the form
<code>
SELECT COUNT(*), MIN(ID), MAX(ID) FROM TEST
</code>
, the query plan includes the line
<code>
/* direct lookup */
</code>
if the data can be read from an index.
</p><p>
For queries of the form
<code>
SELECT DISTINCT CUSTOMER_ID FROM INVOICE
</code>
, the query plan includes the line
<code>
/* distinct */
</code>
if there is an non-unique or multi-column index on this column, and if this column has a low selectivity.
</p><p>
For queries of the form
<code>
SELECT * FROM TEST ORDER BY ID
</code>
, the query plan includes the line
<code>
/* index sorted */
</code>
to indicate there is no separate sorting required.
</p><p>
For queries of the form
<code>
SELECT * FROM TEST GROUP BY ID ORDER BY ID
</code>
, the query plan includes the line
<code>
/* group sorted */
</code>
to indicate there is no separate sorting required.
</p>
<h2
id=
"storage_and_indexes"
>
How Data is Stored and How Indexes Work
</h2>
<p>
Internally, each row in a table is identified by a unique number, the row id.
...
...
@@ -650,6 +736,8 @@ FROM PUBLIC.ADDRESS
/* PUBLIC.ADDRESS.tableScan */
WHERE NAME = 'Miller';
</pre>
<h3>
Indexes
</h3>
<p>
An index internally is basically just a table that contains the indexed column(s), plus the row id:
</p>
...
...
@@ -713,7 +801,13 @@ WHERE FIRST_NAME = 'John';
</pre>
<p>
If your application often queries the table for a phone number, then it makes sense to create
an additional index on it, which then contains the following data:
an additional index on it:
</p>
<pre>
CREATE INDEX IDX_PHONE ON ADDRESS(PHONE);
</pre>
<p>
This index contains the phone number, and the row id:
</p>
<table>
<tr><th>
PHONE
</th><th>
_ROWID_
</th></tr>
...
...
@@ -721,92 +815,31 @@ an additional index on it, which then contains the following data:
<tr><td>
123 456 789
</td><td>
1
</td></tr>
</table>
<h
2
id=
"explain_plan"
>
Statement Execution Plans
</h2
>
<h
3>
Using Multiple Indexes
</h3
>
<p>
The SQL statement
<code>
EXPLAIN
</code>
displays the indexes and optimizations the database uses for a statement.
The following statements support
<code>
EXPLAIN
</code>
:
<code>
SELECT, UPDATE, DELETE, MERGE, INSERT
</code>
.
The following query shows that the database uses the primary key index to search for rows:
Within a query, only one index per logical table is used.
Using the condition
<code>
PHONE = '123 567 789' OR CITY = 'Berne'
</code>
would use a table scan instead of first using the index on the phone number and then the index on the city.
It makes sense to write two queries and combine then using
<code>
UNION
</code>
.
In this case, each individual query uses a different index:
</p>
<pre>
EXPLAIN SELECT * FROM TEST WHERE ID=1;
SELECT
TEST.ID,
TEST.NAME
FROM PUBLIC.TEST
/* PUBLIC.PRIMARY_KEY_2: ID = 1 */
WHERE ID = 1
</pre>
<p>
For joins, the tables in the execution plan are sorted in the order they are processed.
The following query shows the database first processes the table
<code>
INVOICE
</code>
(using the primary key).
For each row, it will additionally check that the value of the column
<code>
AMOUNT
</code>
is larger than zero,
and for those rows the database will search in the table
<code>
CUSTOMER
</code>
(using the primary key).
The query plan contains some redundancy so it is a valid statement.
</p>
<pre>
CREATE TABLE CUSTOMER(ID IDENTITY, NAME VARCHAR);
CREATE TABLE INVOICE(ID IDENTITY,
CUSTOMER_ID INT REFERENCES CUSTOMER(ID),
AMOUNT NUMBER);
EXPLAIN SELECT NAME FROM ADDRESS WHERE PHONE = '123 567 789'
UNION SELECT NAME FROM ADDRESS WHERE CITY = 'Berne';
EXPLAIN SELECT I.ID, C.NAME FROM CUSTOMER C, INVOICE I
WHERE I.ID=10 AND AMOUNT>0 AND C.ID=I.CUSTOMER_ID;
SELECT
I.ID,
C.NAME
FROM PUBLIC.INVOICE I
/* PUBLIC.PRIMARY_KEY_9: ID = 10 */
/* WHERE (I.ID = 10)
AND (AMOUNT > 0)
*/
INNER JOIN PUBLIC.CUSTOMER C
/* PUBLIC.PRIMARY_KEY_5: ID = I.CUSTOMER_ID */
ON 1=1
WHERE (C.ID = I.CUSTOMER_ID)
AND ((I.ID = 10)
AND (AMOUNT > 0))
</pre>
<h3>
Displaying the Scan Count
</h3>
<p>
<code>
EXPLAIN ANALYZE
</code>
additionally shows the scanned rows per table and pages read from disk per table or index.
This will actually execute the query, unlike
<code>
EXPLAIN
</code>
which only prepares it.
The following query scanned 1000 rows, and to do that had to read 85 pages from the data area of the table.
Running the query twice will not list the pages read from disk, because they are now in the cache.
The
<code>
tableScan
</code>
means this query doesn't use an index.
</p>
<pre>
EXPLAIN ANALYZE SELECT * FROM TEST;
SELECT
TEST.ID,
TEST.NAME
FROM PUBLIC.TEST
/* PUBLIC.TEST.tableScan */
/* scanCount: 1000 */
/*
total: 85
TEST.TEST_DATA read: 85 (100%)
*/
(SELECT
NAME
FROM PUBLIC.ADDRESS
/* PUBLIC.IDX_PHONE: PHONE = '123 567 789' */
WHERE PHONE = '123 567 789')
UNION
(SELECT
NAME
FROM PUBLIC.ADDRESS
/* PUBLIC.INDEX_PLACE: CITY = 'Berne' */
WHERE CITY = 'Berne')
</pre>
<h3>
Special Optimizations
</h3>
<p>
For certain queries, the database doesn't need to read all rows, or doesn't need to sort the result even if
<code>
ORDER BY
</code>
is used.
</p><p>
For queries of the form
<code>
SELECT COUNT(*), MIN(ID), MAX(ID) FROM TEST
</code>
, the query plan includes the line
<code>
/* direct lookup */
</code>
if the data can be read from an index.
</p><p>
For queries of the form
<code>
SELECT DISTINCT CUSTOMER_ID FROM INVOICE
</code>
, the query plan includes the line
<code>
/* distinct */
</code>
if there is an non-unique or multi-column index on this column, and if this column has a low selectivity.
</p><p>
For queries of the form
<code>
SELECT * FROM TEST ORDER BY ID
</code>
, the query plan includes the line
<code>
/* index sorted */
</code>
to indicate there is no separate sorting required.
</p><p>
For queries of the form
<code>
SELECT * FROM TEST GROUP BY ID ORDER BY ID
</code>
, the query plan includes the line
<code>
/* group sorted */
</code>
to indicate there is no separate sorting required.
</p>
<h2
id=
"fast_import"
>
Fast Database Import
</h2>
<p>
To speed up large imports, consider using the following options temporarily:
...
...
h2/src/docsrc/html/roadmap.html
浏览文件 @
1f12ebf1
差异被折叠。
点击展开。
h2/src/docsrc/html/tutorial.html
浏览文件 @
1f12ebf1
...
...
@@ -549,8 +549,11 @@ You can rename it to <code>H2Dialect.java</code> and include this as a patch in
or upgrade to a version of Hibernate where this is fixed.
</p>
<p>
When using compatibility modes such as
<code>
MODE=MySQL
</code>
when using Hibernate
is not supported when using
<code>
H2Dialect
</code>
.
When using Hibernate, try to use the
<code>
H2Dialect
</code>
if possible.
When using the
<code>
H2Dialect
</code>
,
compatibility modes such as
<code>
MODE=MySQL
</code>
are not supported.
When using such a compatibility mode, use the Hibernate dialect for the
corresponding database instead of the
<code>
H2Dialect
</code>
.
</p>
<h2
id=
"using_toplink"
>
Using TopLink and Glassfish
</h2>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论