In most cases H2 is a lot faster than all other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer.
@performance_1006_h3
@performance_1007_h3
Embedded
@performance_1007_th
@performance_1008_th
Test Case
@performance_1008_th
@performance_1009_th
Unit
@performance_1009_th
@performance_1010_th
H2
@performance_1010_th
@performance_1011_th
HSQLDB
@performance_1011_th
@performance_1012_th
Derby
@performance_1012_td
Simple: Init
@performance_1013_td
ms
Simple: Init
@performance_1014_td
375
ms
@performance_1015_td
578
375
@performance_1016_td
2797
578
@performance_1017_td
Simple: Query (random)
2797
@performance_1018_td
ms
Simple: Query (random)
@performance_1019_td
250
ms
@performance_1020_td
344
250
@performance_1021_td
1563
344
@performance_1022_td
Simple: Query (sequential)
1563
@performance_1023_td
ms
Simple: Query (sequential)
@performance_1024_td
171
ms
@performance_1025_td
250
171
@performance_1026_td
1469
250
@performance_1027_td
Simple: Update (random)
1469
@performance_1028_td
ms
Simple: Update (random)
@performance_1029_td
641
ms
@performance_1030_td
1609
641
@performance_1031_td
19265
1609
@performance_1032_td
Simple: Delete (sequential)
19265
@performance_1033_td
ms
Simple: Delete (sequential)
@performance_1034_td
172
ms
@performance_1035_td
516
172
@performance_1036_td
6797
516
@performance_1037_td
Simple: Memory Usage
6797
@performance_1038_td
MB
Simple: Memory Usage
@performance_1039_td
14
MB
@performance_1040_td
12
14
@performance_1041_td
12
@performance_1042_td
BenchA: Init
12
@performance_1043_td
ms
BenchA: Init
@performance_1044_td
391
ms
@performance_1045_td
500
391
@performance_1046_td
3750
500
@performance_1047_td
BenchA: Transactions
3750
@performance_1048_td
ms
BenchA: Transactions
@performance_1049_td
5468
ms
@performance_1050_td
2468
5468
@performance_1051_td
16250
2468
@performance_1052_td
BenchA: Memory Usage
16250
@performance_1053_td
MB
BenchA: Memory Usage
@performance_1054_td
14
MB
@performance_1055_td
15
14
@performance_1056_td
9
15
@performance_1057_td
BenchB: Init
9
@performance_1058_td
ms
BenchB: Init
@performance_1059_td
1281
ms
@performance_1060_td
2391
1281
@performance_1061_td
14938
2391
@performance_1062_td
BenchB: Transactions
14938
@performance_1063_td
ms
BenchB: Transactions
@performance_1064_td
2094
ms
@performance_1065_td
1140
2094
@performance_1066_td
3828
1140
@performance_1067_td
BenchB: Memory Usage
3828
@performance_1068_td
MB
BenchB: Memory Usage
@performance_1069_td
16
MB
@performance_1070_td
11
16
@performance_1071_td
9
11
@performance_1072_td
BenchC: Init
9
@performance_1073_td
ms
BenchC: Init
@performance_1074_td
984
ms
@performance_1075_td
547
984
@performance_1076_td
5250
547
@performance_1077_td
BenchC: Transactions
5250
@performance_1078_td
ms
BenchC: Transactions
@performance_1079_td
2860
ms
@performance_1080_td
58219
2860
@performance_1081_td
11204
58219
@performance_1082_td
BenchC: Memory Usage
11204
@performance_1083_td
MB
BenchC: Memory Usage
@performance_1084_td
19
MB
@performance_1085_td
19
@performance_1086_td
9
19
@performance_1087_td
Executed Statements
9
@performance_1088_td
#
Executed Statements
@performance_1089_td
594255
#
@performance_1090_td
594255
...
...
@@ -3443,382 +3443,382 @@ Executed Statements
594255
@performance_1092_td
Total Time
594255
@performance_1093_td
ms
Total Time
@performance_1094_td
14687
ms
@performance_1095_td
68562
14687
@performance_1096_td
87111
68562
@performance_1097_td
Statement per Second
87111
@performance_1098_td
#
Statement per Second
@performance_1099_td
40461
#
@performance_1100_td
8667
40461
@performance_1101_td
8667
@performance_1102_td
6821
@performance_1102_h3
@performance_1103_h3
Client-Server
@performance_1103_th
@performance_1104_th
Test Case
@performance_1104_th
@performance_1105_th
Unit
@performance_1105_th
@performance_1106_th
H2
@performance_1106_th
@performance_1107_th
HSQLDB
@performance_1107_th
@performance_1108_th
Derby
@performance_1108_th
@performance_1109_th
PostgreSQL
@performance_1109_th
@performance_1110_th
MySQL
@performance_1110_td
Simple: Init
@performance_1111_td
ms
Simple: Init
@performance_1112_td
3047
ms
@performance_1113_td
2547
3047
@performance_1114_td
6907
2547
@performance_1115_td
4234
6907
@performance_1116_td
3594
4234
@performance_1117_td
Simple: Query (random)
3594
@performance_1118_td
ms
Simple: Query (random)
@performance_1119_td
3547
ms
@performance_1120_td
2641
3547
@performance_1121_td
8781
2641
@performance_1122_td
5375
8781
@performance_1123_td
3140
5375
@performance_1124_td
Simple: Query (sequential)
3140
@performance_1125_td
ms
Simple: Query (sequential)
@performance_1126_td
3390
ms
@performance_1127_td
2531
3390
@performance_1128_td
8859
2531
@performance_1129_td
4906
8859
@performance_1130_td
3016
4906
@performance_1131_td
Simple: Update (random)
3016
@performance_1132_td
ms
Simple: Update (random)
@performance_1133_td
3235
ms
@performance_1134_td
3531
3235
@performance_1135_td
22344
3531
@performance_1136_td
5828
22344
@performance_1137_td
5187
5828
@performance_1138_td
Simple: Delete (sequential)
5187
@performance_1139_td
ms
Simple: Delete (sequential)
@performance_1140_td
1421
ms
@performance_1141_td
1235
1421
@performance_1142_td
8219
1235
@performance_1143_td
2484
8219
@performance_1144_td
1829
2484
@performance_1145_td
Simple: Memory Usage
1829
@performance_1146_td
MB
Simple: Memory Usage
@performance_1147_td
15
MB
@performance_1148_td
10
15
@performance_1149_td
15
10
@performance_1150_td
0
15
@performance_1151_td
0
@performance_1152_td
BenchA: Init
0
@performance_1153_td
ms
BenchA: Init
@performance_1154_td
2687
ms
@performance_1155_td
2343
2687
@performance_1156_td
6000
2343
@performance_1157_td
4000
6000
@performance_1158_td
4000
@performance_1159_td
BenchA: Transactions
4000
@performance_1160_td
ms
BenchA: Transactions
@performance_1161_td
12938
ms
@performance_1162_td
9579
12938
@performance_1163_td
26610
9579
@performance_1164_td
16250
26610
@performance_1165_td
10782
16250
@performance_1166_td
BenchA: Memory Usage
10782
@performance_1167_td
MB
BenchA: Memory Usage
@performance_1168_td
15
MB
@performance_1169_td
16
15
@performance_1170_td
10
16
@performance_1171_td
0
10
@performance_1172_td
0
@performance_1173_td
BenchB: Init
0
@performance_1174_td
ms
BenchB: Init
@performance_1175_td
9641
ms
@performance_1176_td
10094
9641
@performance_1177_td
28282
10094
@performance_1178_td
17468
28282
@performance_1179_td
11344
17468
@performance_1180_td
BenchB: Transactions
11344
@performance_1181_td
ms
BenchB: Transactions
@performance_1182_td
3984
ms
@performance_1183_td
3312
3984
@performance_1184_td
6671
3312
@performance_1185_td
7797
6671
@performance_1186_td
3375
7797
@performance_1187_td
BenchB: Memory Usage
3375
@performance_1188_td
MB
BenchB: Memory Usage
@performance_1189_td
16
MB
@performance_1190_td
13
16
@performance_1191_td
8
13
@performance_1192_td
0
8
@performance_1193_td
0
@performance_1194_td
BenchC: Init
0
@performance_1195_td
ms
BenchC: Init
@performance_1196_td
2031
ms
@performance_1197_td
1516
2031
@performance_1198_td
7391
1516
@performance_1199_td
2297
7391
@performance_1200_td
3406
2297
@performance_1201_td
BenchC: Transactions
3406
@performance_1202_td
ms
BenchC: Transactions
@performance_1203_td
9750
ms
@performance_1204_td
58734
9750
@performance_1205_td
20937
58734
@performance_1206_td
11172
20937
@performance_1207_td
7469
11172
@performance_1208_td
BenchC: Memory Usage
7469
@performance_1209_td
MB
BenchC: Memory Usage
@performance_1210_td
20
MB
@performance_1211_td
15
20
@performance_1212_td
14
15
@performance_1213_td
0
14
@performance_1214_td
0
@performance_1215_td
Executed Statements
0
@performance_1216_td
#
Executed Statements
@performance_1217_td
594255
#
@performance_1218_td
594255
...
...
@@ -3833,537 +3833,540 @@ Executed Statements
594255
@performance_1222_td
Total Time
594255
@performance_1223_td
ms
Total Time
@performance_1224_td
55671
ms
@performance_1225_td
98063
55671
@performance_1226_td
151001
98063
@performance_1227_td
81811
151001
@performance_1228_td
57142
81811
@performance_1229_td
Statement per Second
57142
@performance_1230_td
#
Statement per Second
@performance_1231_td
10674
#
@performance_1232_td
6059
10674
@performance_1233_td
3935
6059
@performance_1234_td
7263
3935
@performance_1235_td
7263
@performance_1236_td
10399
@performance_1236_h3
@performance_1237_h3
Benchmark Results and Comments
@performance_1237_h4
@performance_1238_h4
H2
@performance_1238_p
@performance_1239_p
Version 1.0 (2007-09-15) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol: The engine waits 20 ms after opening a database to ensure the database files are not opened by another process.
@performance_1239_h4
@performance_1240_h4
HSQLDB
@performance_1240_p
@performance_1241_p
Version 1.8.0.8 was used for the test. Cached tables are used in this test (hsqldb.default_table_type=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC: Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join:
@performance_1241_p
@performance_1242_p
The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. A disadvantage in HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the database is created whenever the database is opened or closed.
@performance_1242_h4
@performance_1243_h4
Derby
@performance_1243_p
@performance_1244_p
Version 10.3.1.4 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will not be easy for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified: Leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby.
@performance_1244_h4
@performance_1245_h4
PostgreSQL
@performance_1245_p
@performance_1246_p
Version 8.1.4 was used for the test. The following options where changed in postgresql.conf: fsync = off, commit_delay = 1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
@performance_1246_h4
@performance_1247_h4
MySQL
@performance_1247_p
@performance_1248_p
Version 5.0.22 was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
@performance_1248_h4
@performance_1249_h4
Firebird
@performance_1249_p
@performance_1250_p
Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome.
@performance_1250_h4
@performance_1251_h4
Why Oracle / MS SQL Server / DB2 are Not Listed
@performance_1251_p
@performance_1252_p
The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions.
@performance_1252_h3
@performance_1253_h3
About this Benchmark
@performance_1253_h4
@performance_1254_h4
Number of Connections
@performance_1254_p
@performance_1255_p
This is mostly a single-connection benchmark. BenchB uses multiple connections, the other tests one connection.
@performance_1255_h4
@performance_1256_h4
Real-World Tests
@performance_1256_p
@performance_1257_p
Good benchmarks emulate real-world use cases. This benchmark includes 3 test cases: A simple test case with one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also: www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded.
@performance_1257_h4
@performance_1258_h4
Comparing Embedded with Server Databases
@performance_1258_p
@performance_1259_p
This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine than the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested.
@performance_1259_h4
@performance_1260_h4
Test Platform
@performance_1260_p
@performance_1261_p
This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5.
@performance_1261_h4
@performance_1262_h4
Multiple Runs
@performance_1262_p
@performance_1263_p
When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, the last run counts.
@performance_1263_h4
@performance_1264_h4
Memory Usage
@performance_1264_p
@performance_1265_p
It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved in databases by using a bigger in-memory cache, but there is only a limited amount of memory available on the system. HSQLDB tables are kept fully in memory by default, this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases.
@performance_1265_h4
@performance_1266_h4
Delayed Operations
@performance_1266_p
@performance_1267_p
Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially).
@performance_1267_h4
@performance_1268_h4
Transaction Commit / Durability
@performance_1268_p
@performance_1269_p
Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling fsync() slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used.
@performance_1269_h4
@performance_1270_h4
Using Prepared Statements
@performance_1270_p
@performance_1271_p
Wherever possible, the test cases use prepared statements.
@performance_1271_h4
@performance_1272_h4
Currently Not Tested: Startup Time
@performance_1272_p
@performance_1273_p
The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. That means the Open/Close time listed is for opening a connection if the database is already in use.
@performance_1273_h3
@performance_1274_h2
PolePosition Benchmark
@performance_1274_p
@performance_1275_p
The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o.
@performance_1275_th
@performance_1276_th
Test Case
@performance_1276_th
@performance_1277_th
Unit
@performance_1277_th
@performance_1278_th
H2
@performance_1278_th
@performance_1279_th
HSQLDB
@performance_1279_th
@performance_1280_th
MySQL
@performance_1280_td
@performance_1281_td
Melbourne write
@performance_1281_td
@performance_1282_td
ms
@performance_1282_td
@performance_1283_td
369
@performance_1283_td
@performance_1284_td
249
@performance_1284_td
@performance_1285_td
2022
@performance_1285_td
@performance_1286_td
Melbourne read
@performance_1286_td
@performance_1287_td
ms
@performance_1287_td
@performance_1288_td
47
@performance_1288_td
@performance_1289_td
49
@performance_1289_td
@performance_1290_td
93
@performance_1290_td
@performance_1291_td
Melbourne read_hot
@performance_1291_td
@performance_1292_td
ms
@performance_1292_td
@performance_1293_td
24
@performance_1293_td
@performance_1294_td
43
@performance_1294_td
@performance_1295_td
95
@performance_1295_td
@performance_1296_td
Melbourne delete
@performance_1296_td
@performance_1297_td
ms
@performance_1297_td
@performance_1298_td
147
@performance_1298_td
@performance_1299_td
133
@performance_1299_td
@performance_1300_td
176
@performance_1300_td
@performance_1301_td
Sepang write
@performance_1301_td
@performance_1302_td
ms
@performance_1302_td
@performance_1303_td
965
@performance_1303_td
@performance_1304_td
1201
@performance_1304_td
@performance_1305_td
3213
@performance_1305_td
@performance_1306_td
Sepang read
@performance_1306_td
@performance_1307_td
ms
@performance_1307_td
@performance_1308_td
765
@performance_1308_td
@performance_1309_td
948
@performance_1309_td
@performance_1310_td
3455
@performance_1310_td
@performance_1311_td
Sepang read_hot
@performance_1311_td
@performance_1312_td
ms
@performance_1312_td
@performance_1313_td
789
@performance_1313_td
@performance_1314_td
859
@performance_1314_td
@performance_1315_td
3563
@performance_1315_td
@performance_1316_td
Sepang delete
@performance_1316_td
@performance_1317_td
ms
@performance_1317_td
@performance_1318_td
1384
@performance_1318_td
@performance_1319_td
1596
@performance_1319_td
@performance_1320_td
6214
@performance_1320_td
@performance_1321_td
Bahrain write
@performance_1321_td
@performance_1322_td
ms
@performance_1322_td
@performance_1323_td
1186
@performance_1323_td
@performance_1324_td
1387
@performance_1324_td
@performance_1325_td
6904
@performance_1325_td
@performance_1326_td
Bahrain query_indexed_string
@performance_1326_td
@performance_1327_td
ms
@performance_1327_td
@performance_1328_td
336
@performance_1328_td
@performance_1329_td
170
@performance_1329_td
@performance_1330_td
693
@performance_1330_td
@performance_1331_td
Bahrain query_string
@performance_1331_td
@performance_1332_td
ms
@performance_1332_td
@performance_1333_td
18064
@performance_1333_td
@performance_1334_td
39703
@performance_1334_td
@performance_1335_td
41243
@performance_1335_td
@performance_1336_td
Bahrain query_indexed_int
@performance_1336_td
@performance_1337_td
ms
@performance_1337_td
@performance_1338_td
104
@performance_1338_td
@performance_1339_td
134
@performance_1339_td
@performance_1340_td
678
@performance_1340_td
@performance_1341_td
Bahrain update
@performance_1341_td
@performance_1342_td
ms
@performance_1342_td
@performance_1343_td
191
@performance_1343_td
@performance_1344_td
87
@performance_1344_td
@performance_1345_td
159
@performance_1345_td
@performance_1346_td
Bahrain delete
@performance_1346_td
@performance_1347_td
ms
@performance_1347_td
@performance_1348_td
1215
@performance_1348_td
@performance_1349_td
729
@performance_1349_td
@performance_1350_td
6812
@performance_1350_td
@performance_1351_td
Imola retrieve
@performance_1351_td
@performance_1352_td
ms
@performance_1352_td
@performance_1353_td
198
@performance_1353_td
@performance_1354_td
194
@performance_1354_td
@performance_1355_td
4036
@performance_1355_td
@performance_1356_td
Barcelona write
@performance_1356_td
@performance_1357_td
ms
@performance_1357_td
@performance_1358_td
413
@performance_1358_td
@performance_1359_td
832
@performance_1359_td
@performance_1360_td
3191
@performance_1360_td
@performance_1361_td
Barcelona read
@performance_1361_td
@performance_1362_td
ms
@performance_1362_td
@performance_1363_td
119
@performance_1363_td
@performance_1364_td
160
@performance_1364_td
@performance_1365_td
1177
@performance_1365_td
@performance_1366_td
Barcelona query
@performance_1366_td
@performance_1367_td
ms
@performance_1367_td
@performance_1368_td
20
@performance_1368_td
@performance_1369_td
5169
@performance_1369_td
@performance_1370_td
101
@performance_1370_td
@performance_1371_td
Barcelona delete
@performance_1371_td
@performance_1372_td
ms
@performance_1372_td
@performance_1373_td
388
@performance_1373_td
@performance_1374_td
319
@performance_1374_td
@performance_1375_td
3287
@performance_1375_td
@performance_1376_td
Total
@performance_1376_td
@performance_1377_td
ms
@performance_1377_td
@performance_1378_td
26724
@performance_1378_td
@performance_1379_td
53962
@performance_1379_td
@performance_1380_td
87112
@performance_1380_h2
@performance_1381_h2
Application Profiling
@performance_1381_h3
@performance_1382_h3
Analyze First
@performance_1382_p
@performance_1383_p
Before trying to optimize the performance, it is important to know where the time is actually spent. The same is true for memory problems. Premature or 'blind' optimization should be avoided, as it is not an efficient way to solve the problem. There are various ways to analyze the application. In some situations it is possible to compare two implementations and use System.currentTimeMillis() to find out which one is faster. But this does not work for complex applications with many modules, and for memory problems. A very good tool to measure both the memory and the CPU is the <a href="http://www.yourkit.com">YourKit Java Profiler</a> . This tool is also used to optimize the performance and memory footprint of this database engine.
@performance_1383_h2
@performance_1384_h2
Database Performance Tuning
@performance_1384_h3
@performance_1385_h3
Virus Scanners
@performance_1385_p
@performance_1386_p
Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine does never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow excluding file endings. Make sure files ending with .db are not scanned.
@performance_1386_h3
@performance_1387_h3
Using the Trace Options
@performance_1387_p
@performance_1388_p
If the main performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see <a href="features.html#trace_options">Using the Trace Options</a> .
@performance_1388_h3
@performance_1389_h3
Index Usage
@performance_1389_p
@performance_1390_p
This database uses indexes to improve the performance of SELECT, UPDATE and DELETE statements. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are not used to order result sets: The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement.
@performance_1390_h3
@performance_1391_h3
Optimizer
@performance_1391_p
@performance_1392_p
This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated.
@performance_1392_h3
@performance_1393_h3
Expression Optimization
@performance_1393_p
@performance_1394_p
After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all.
@performance_1394_h3
@performance_1395_h3
COUNT(*) Optimization
@performance_1395_p
@performance_1396_p
If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table.
When executing a query, at most one index per joined table can be used. If the same table is joined multiple times, for each join only one index is used. Example: for the query SELECT * FROM TEST T1, TEST T2 WHERE T1.NAME='A' AND T2.ID=T1.ID, two index can be used, in this case the index on NAME for T1 and the index on ID for T2.
@performance_1398_p
@performance_1399_p
If a table has multiple indexes, sometimes more than one index could be used. Example: if there is a table TEST(ID, NAME, FIRSTNAME) and an index on each column, then two indexes could be used for the query SELECT * FROM TEST WHERE NAME='A' AND FIRSTNAME='B', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of values in a column. A selectivity of 100 means each value appears only once, and a selectivity of 1 means the same value appears in many or most rows. For the query above, the index on NAME should be used if the table contains more distinct names than first names.
@performance_1399_p
@performance_1400_p
The SQL statement ANALYZE can be used to automatically estimate the selectivity of the columns in the tables. This command should be run from time to time to improve the query plans generated by the optimizer.
@quickstartText_1000_h1
...
...
@@ -4558,402 +4561,417 @@ Java Web Start / JNLP
@tutorial_1011_a
Fulltext Search
@tutorial_1012_h2
@tutorial_1012_a
User Defined Variables
@tutorial_1013_h2
Starting and Using the H2 Console
@tutorial_1013_p
@tutorial_1014_p
This application lets you access a SQL database using a browser interface. This can be a H2 database, or another database that supports the JDBC API.
@tutorial_1014_p
@tutorial_1015_p
This is a client / server application, so both a server and a client (a browser) are required to run it.
@tutorial_1015_p
@tutorial_1016_p
Depending on your platform and environment, there are multiple ways to start the application:
@tutorial_1016_th
@tutorial_1017_th
OS
@tutorial_1017_th
@tutorial_1018_th
Start
@tutorial_1018_td
@tutorial_1019_td
Windows
@tutorial_1019_td
@tutorial_1020_td
Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]
@tutorial_1020_td
@tutorial_1021_td
When using the Sun JDK 1.4 or 1.5, a window with the title 'H2 Console ' should appear. When using the Sun JDK 1.6, an icon will be added to the system tray:
@tutorial_1021_td
@tutorial_1022_td
If you don't get the window and the system tray icon, then maybe Java is not installed correctly (in this case, try another way to start the application). A browser window should open and point to the Login page http://localhost:8082).
@tutorial_1022_td
@tutorial_1023_td
Windows
@tutorial_1023_td
@tutorial_1024_td
Open a file browser, navigate to h2/bin, and double click on h2.bat.
@tutorial_1024_td
@tutorial_1025_td
A console window appears. If there is a problem, you will see an error message in this window. A browser window will open and point to the Login page (URL: http://localhost:8082).
@tutorial_1025_td
@tutorial_1026_td
Any
@tutorial_1026_td
@tutorial_1027_td
Open a console window, navigate to the directory 'h2/bin' and type:
@tutorial_1027_h3
@tutorial_1028_h3
Firewall
@tutorial_1028_p
@tutorial_1029_p
If you start the server, you may get a security warning from the firewall (if you have installed one). If you don't want other computers in the network to access the application on your machine, you can let the firewall block those connections. The connection from the local machine will still work. Only if you want other computers to access the database on this computer, you need allow remote connections in the firewall.
@tutorial_1029_p
@tutorial_1030_p
A small firewall is already built into the server: other computers may not connect to the server by default. To change this, go to 'Preferences' and select 'Allow connections from other computers'.
@tutorial_1030_h3
@tutorial_1031_h3
Native Version
@tutorial_1031_p
@tutorial_1032_p
The native version does not require Java, because it is compiled using GCJ. However H2 does currently not run stable with GCJ on Windows It is possible to compile the software to different platforms.
@tutorial_1032_h3
@tutorial_1033_h3
Testing Java
@tutorial_1033_p
@tutorial_1034_p
To check the Java version you have installed, open a command prompt and type:
@tutorial_1034_p
@tutorial_1035_p
If you get an error message, you may need to add the Java binary directory to the path environment variable.
@tutorial_1035_h3
@tutorial_1036_h3
Error Message 'Port is in use'
@tutorial_1036_p
@tutorial_1037_p
You can only start one instance of the H2 Console, otherwise you will get the following error message: <code>Port is in use, maybe another ... server already running on...</code> . It is possible to start multiple console applications on the same computer (using different ports), but this is usually not required as the console supports multiple concurrent connections.
@tutorial_1037_h3
@tutorial_1038_h3
Using another Port
@tutorial_1038_p
@tutorial_1039_p
If the port is in use by another application, you may want to start the H2 Console on a different port. This can be done by changing the port in the file .h2.server.properties. This file is stored in the user directory (for Windows, this is usually in "Documents and Settings/<username>"). The relevant entry is webPort.
@tutorial_1039_h3
@tutorial_1040_h3
Starting Successfully
@tutorial_1040_p
@tutorial_1041_p
If starting the server from a console window was successful, a new window will open and display the following text:
@tutorial_1041_p
@tutorial_1042_p
Don't click inside this window; otherwise you might block the application (if you have the Fast-Edit mode enabled).
@tutorial_1042_h3
@tutorial_1043_h3
Connecting to the Server using a Browser
@tutorial_1043_p
@tutorial_1044_p
If the server started successfully, you can connect to it using a web browser. The browser needs to support JavaScript, frames and cascading stylesheets (css). If you started the server on the same computer as the browser, go to http://localhost:8082 in the browser. If you want to connect to the application from another computer, you need to provide the IP address of the server, for example: http://192.168.0.2:8082. If you enabled SSL on the server side, the URL needs to start with HTTPS.
@tutorial_1044_h3
@tutorial_1045_h3
Multiple Concurrent Sessions
@tutorial_1045_p
@tutorial_1046_p
Multiple concurrent browser sessions are supported. As that the database objects reside on the server, the amount of concurrent work is limited by the memory available to the server application.
@tutorial_1046_h3
@tutorial_1047_h3
Application Properties
@tutorial_1047_p
@tutorial_1048_p
Starting the server will create a configuration file in you local home directory called <code>.h2.server.properties</code> . For Windows installations, this file will be in the directory <code>C:\Documents and Settings\[username]</code> . This file contains the settings of the application.
@tutorial_1048_h3
@tutorial_1049_h3
Login
@tutorial_1049_p
@tutorial_1050_p
At the login page, you need to provide connection information to connect to a database. Set the JDBC driver class of your database, the JDBC URL, user name and password. If you are done, click [Connect].
@tutorial_1050_p
@tutorial_1051_p
You can save and reuse previously saved settings. The settings are stored in the Application Properties file.
@tutorial_1051_h3
@tutorial_1052_h3
Error Messages
@tutorial_1052_p
@tutorial_1053_p
Error messages in are shown in red. You can show/hide the stack trace of the exception by clicking on the message.
@tutorial_1053_h3
@tutorial_1054_h3
Adding Database Drivers
@tutorial_1054_p
@tutorial_1055_p
Additional database drivers can be registered by adding the Jar file location of the driver to the environment variables H2DRIVERS or CLASSPATH. Example (Windows): To add the database driver library C:\Programs\hsqldb\lib\hsqldb.jar, set the environment variable H2DRIVERS to C:\Programs\hsqldb\lib\hsqldb.jar.
@tutorial_1055_p
@tutorial_1056_p
Multiple drivers can be set; each entry needs to be separated with a ';' (Windows) or ':' (other operating systems). Spaces in the path names are supported. The settings must not be quoted.
@tutorial_1056_p
@tutorial_1057_p
Only the Java version supports additional drivers (this feature is not supported by the Native version).
@tutorial_1057_h3
@tutorial_1058_h3
Using the Application
@tutorial_1058_p
@tutorial_1059_p
The application has three main panels, the toolbar on top, the tree on the left and the query / result panel on the right. The database objects (for example, tables) are listed on the left panel. Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command.
@tutorial_1059_h3
@tutorial_1060_h3
Inserting Table Names or Column Names
@tutorial_1060_p
@tutorial_1061_p
The table name and column names can be inserted in the script by clicking them in the tree. If you click on a table while the query is empty, a 'SELECT * FROM ...' is added as well. While typing a query, the table that was used is automatically expanded in the tree. For, example if you type 'SELECT * FROM TEST T WHERE T.' then the table TEST is automatically expanded in the tree.
@tutorial_1061_h3
@tutorial_1062_h3
Disconnecting and Stopping the Application
@tutorial_1062_p
@tutorial_1063_p
On the browser, click 'Disconnect' on the toolbar panel. You will be logged out of the database. However, the server is still running and ready to accept new sessions.
@tutorial_1063_p
@tutorial_1064_p
To stop the server, right click on the system tray icon and select [Exit]. If you don't have the icon (because you started it in another way), press [Ctrl]+[C] on the console where the server was started (Windows), or close the console window.
@tutorial_1064_h2
@tutorial_1065_h2
Connecting to a Database using JDBC
@tutorial_1065_p
@tutorial_1066_p
To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code:
@tutorial_1066_p
@tutorial_1067_p
This code first loads the driver ( <code>Class.forName()</code> ) and then opens a connection (using <code>DriverManager.getConnection()</code> ). The driver name is <code>"org.h2.Driver"</code> in every case. The database URL always needs to start with <code>jdbc:h2:</code> to be recognized by this database. The second parameter in the <code>getConnection()</code> call is the user name ('sa' for System Administrator in this example). The third parameter is the password. Please note that in this database, user names are not case sensitive, but passwords are case sensitive.
@tutorial_1067_h2
@tutorial_1068_h2
Creating New Databases
@tutorial_1068_p
@tutorial_1069_p
By default, if the database specified in the URL does not yet exist, a new (empty) database is created automatically. The user that created the database automatically becomes the administrator of this database.
@tutorial_1069_h2
@tutorial_1070_h2
Using the Server
@tutorial_1070_p
@tutorial_1071_p
H2 currently supports three servers: a Web Server, a TCP Server and an ODBC Server. The servers can be started in different ways.
@tutorial_1071_h3
@tutorial_1072_h3
Starting the Server from Command Line
@tutorial_1072_p
@tutorial_1073_p
To start the Server from the command line with the default settings, run
@tutorial_1073_p
@tutorial_1074_p
This will start the Server with the default options. To get the list of options and default values, run
@tutorial_1074_p
@tutorial_1075_p
There are options available to use a different ports, and start or not start parts of the Server and so on. For details, see the API documentation of the Server tool.
@tutorial_1075_h3
@tutorial_1076_h3
Connecting to the TCP Server
@tutorial_1076_p
@tutorial_1077_p
To remotly connect to a database using the TCP server, use the following driver and database URL:
@tutorial_1077_li
@tutorial_1078_li
JDBC driver class: org.h2.Driver
@tutorial_1078_li
@tutorial_1079_li
Database URL: jdbc:h2:tcp://localhost/~/test
@tutorial_1079_p
@tutorial_1080_p
For details about the database URL, see also in Features.
@tutorial_1080_h3
@tutorial_1081_h3
Starting the Server within an Application
@tutorial_1081_p
@tutorial_1082_p
It is also possible to start and stop a Server from within an application. Sample code:
@tutorial_1082_h3
@tutorial_1083_h3
Stopping a TCP Server from Another Process
@tutorial_1083_p
@tutorial_1084_p
The TCP Server can be stopped from another process. To stop the server from the command line, run:
@tutorial_1084_p
@tutorial_1085_p
To stop the server from a user application, use the following code:
@tutorial_1085_p
@tutorial_1086_p
This function will call System.exit on the server. This function should be called after all connection to the databases are closed to avoid recovery when the databases are opened the next time. To stop remote server, remote connections must be enabled on the server.
@tutorial_1086_h3
@tutorial_1087_h3
Limitations of the Server
@tutorial_1087_p
@tutorial_1088_p
There currently are a few limitations when using the server or cluster mode:
@tutorial_1088_li
@tutorial_1089_li
Statement.cancel() is only supported in embedded mode. A connection can only execute one operation at a time in server or cluster mode, and is blocked until this operation is finished.
@tutorial_1089_h2
@tutorial_1090_h2
Using Hibernate
@tutorial_1090_p
@tutorial_1091_p
This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, or the native H2 Dialect that is available in the file src/tools/org/h2/tools/hibernate/H2Dialect.txt. The H2 dialect is included in newer version of Hibernate. For versions where the dialect is missing, you need to copy the file into the folder src\org\hibernate\dialect (Hibernate 3.1), rename it to H2Dialect.java and re-compile hibernate.
@tutorial_1091_h2
@tutorial_1092_h2
Using Databases in Web Applications
@tutorial_1092_p
@tutorial_1093_p
There are multiple ways to access a database from within web applications. Here are some examples if you use Tomcat or JBoss.
@tutorial_1093_h3
@tutorial_1094_h3
Embedded Mode
@tutorial_1094_p
@tutorial_1095_p
The (currently) most simple solution is to use the database in the embedded mode, that means open a connection in your application when it starts (a good solution is using a Servlet Listener, see below), or when a session starts. A database can be accessed from multiple sessions and applications at the same time, as long as they run in the same process. Most Servlet Containers (for example Tomcat) are just using one process, so this is not a problem (unless you run Tomcat in clustered mode). Tomcat uses multiple threads and multiple classloaders. If multiple applications access the same database at the same time, you need to put the database jar in the shared/lib or server/lib directory. It is a good idea to open the database when the web application starts, and close it when the web applications stops. If using multiple applications, only one (any) of them needs to do that. In the application, an idea is to use one connection per Session, or even one connection per request (action). Those connections should be closed after use if possible (but it's not that bad if they don't get closed).
@tutorial_1095_h3
@tutorial_1096_h3
Server Mode
@tutorial_1096_p
@tutorial_1097_p
The server mode is similar, but it allows you to run the server in another process.
@tutorial_1097_h3
@tutorial_1098_h3
Using a Servlet Listener to Start and Stop a Database
@tutorial_1098_p
@tutorial_1099_p
Add the h2.jar file your web application, and add the following snippet to your web.xml file (after context-param and before filter):
@tutorial_1099_p
@tutorial_1100_p
For details on how to access the database, see the code DbStarter.java
@tutorial_1100_h2
@tutorial_1101_h2
CSV (Comma Separated Values) Support
@tutorial_1101_p
@tutorial_1102_p
The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE, and the CSV library can be used outside the database as a standalone tool.
@tutorial_1102_h3
@tutorial_1103_h3
Writing a CSV File from Within a Database
@tutorial_1103_p
@tutorial_1104_p
The built-in function CSVWRITE can be used to create a CSV file from a query. Example:
@tutorial_1104_h3
@tutorial_1105_h3
Reading a CSV File from Within a Database
@tutorial_1105_p
@tutorial_1106_p
A CSV file can be read using the function CSVREAD. Example:
@tutorial_1106_h3
@tutorial_1107_h3
Writing a CSV File from a Java Application
@tutorial_1107_p
@tutorial_1108_p
The CSV tool can be used in a Java application even when not using a database at all. Example:
@tutorial_1108_h3
@tutorial_1109_h3
Reading a CSV File from a Java Application
@tutorial_1109_p
@tutorial_1110_p
It is possible to read a CSV file without opening a database. Example:
@tutorial_1110_h2
@tutorial_1111_h2
Upgrade, Backup, and Restore
@tutorial_1111_h3
@tutorial_1112_h3
Database Upgrade
@tutorial_1112_p
@tutorial_1113_p
The recommended way to upgrade from one version of the database engine to the next version is to create a backup of the database (in the form of a SQL script) using the old engine, and then execute the SQL script using the new engine.
@tutorial_1113_h3
@tutorial_1114_h3
Backup using the Script Tool
@tutorial_1114_p
@tutorial_1115_p
There are different ways to backup a database. For example, it is possible to copy the database files. However, this is not recommended while the database is in use. Also, the database files are not human readable and quite large. The recommended way to backup a database is to create a compressed SQL script file. This can be done using the Script tool:
@tutorial_1115_p
@tutorial_1116_p
It is also possible to use the SQL command SCRIPT to create the backup of the database. For more information about the options, see the SQL command SCRIPT. The backup can be done remotely, however the file will be created on the server side. The built in FTP server could be used to retrieve the file from the server.
@tutorial_1116_h3
@tutorial_1117_h3
Restore from a Script
@tutorial_1117_p
@tutorial_1118_p
To restore a database from a SQL script file, you can use the RunScript tool:
@tutorial_1118_p
@tutorial_1119_p
For more information about the options, see the SQL command RUNSCRIPT. The restore can be done remotely, however the file needs to be on the server side. The built in FTP server could be used to copy the file to the server. It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. SQL script files may contain references to other script files, in the form of RUNSCRIPT commands. However, when using the server mode, the references script files need to be available on the server side.
@tutorial_1119_h3
@tutorial_1120_h3
Online Backup
@tutorial_1120_p
@tutorial_1121_p
The BACKUP SQL statement and the Backup tool both create a zip file with all database files. However, the contents of this file are not human readable. Other than the SCRIPT statement, the BACKUP statement does not lock the database objects, and therefore does not block other users. The resulting backup is transactionally consistent:
@tutorial_1121_p
@tutorial_1122_p
The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; the database must not be in use while running this program.
@tutorial_1122_h2
@tutorial_1123_h2
Using OpenOffice Base
@tutorial_1123_p
@tutorial_1124_p
OpenOffice.org Base supports database access over the JDBC API. To connect to a H2 database using OpenOffice Base, you first need to add the JDBC driver to OpenOffice. The steps to connect to a H2 database are:
@tutorial_1124_li
@tutorial_1125_li
Stop OpenOffice, including the autostart
@tutorial_1125_li
@tutorial_1126_li
Copy h2.jar into the directory <OpenOffice>\program\classes
@tutorial_1126_li
@tutorial_1127_li
Start OpenOffice Base
@tutorial_1127_li
@tutorial_1128_li
Connect to an existing database, select JDBC, [Next]
@tutorial_1128_li
@tutorial_1129_li
Example datasource URL: jdbc:h2:c:/temp/test
@tutorial_1129_li
@tutorial_1130_li
JDBC driver class: org.h2.Driver
@tutorial_1130_p
@tutorial_1131_p
Now you can access the database stored in the directory C:/temp.
@tutorial_1131_h2
@tutorial_1132_h2
Java Web Start / JNLP
@tutorial_1132_p
@tutorial_1133_p
When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following exception will occur: java.security.AccessControlException: access denied (java.io.FilePermission ... read). Example permission tags:
@tutorial_1133_h2
@tutorial_1134_h2
Fulltext Search
@tutorial_1134_p
@tutorial_1135_p
H2 supports Lucene full text search and native full text search implementation.
@tutorial_1135_h3
@tutorial_1136_h3
Using the Native Full Text Search
@tutorial_1136_p
@tutorial_1137_p
To initialize, call:
@tutorial_1137_p
@tutorial_1138_p
You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using:
@tutorial_1138_p
@tutorial_1139_p
PUBLIC is the schema, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in read time. To search the index, use the following query:
@tutorial_1139_p
@tutorial_1140_p
You can also call the index from within a Java application:
@tutorial_1140_h3
@tutorial_1141_h3
Using the Lucene Fulltext Search
@tutorial_1141_p
@tutorial_1142_p
To use the Lucene full text search, you need the Lucene library in the classpath. How his is done depends on the application; if you use the H2 Console, you can add the Lucene jar file to the the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene full text search in a database, call:
@tutorial_1142_p
@tutorial_1143_p
You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using:
@tutorial_1143_p
@tutorial_1144_p
PUBLIC is the schema, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in read time. To search the index, use the following query:
@tutorial_1144_p
@tutorial_1145_p
You can also call the index from within a Java application:
@tutorial_1146_h2
User Defined Variables
@tutorial_1147_p
This database supports user defined variables. Variables start with @ and can be used whereever expressions or parameters are used. Variables not persisted and session scoped, that means only visible for the session where they are defined. A value is usually assigned using the SET command:
@tutorial_1148_p
It is also possible to change a value using the SET() method. This is useful in queries:
@tutorial_1149_p
Variables that are not set evaluate to NULL. The data type of a user defined variable is the data type of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. There are no restrictions on the assigned values, large objects (LOBs) are supported as well.
@@ -3070,10 +3070,10 @@ JDBC、 (部分的な) ODBC API; Web クライアントアプリケーション
#Version 1.0.65 (2008-01-18):
@mainWeb_1008_a
#Windows Installer (2.8 MB)
#Windows Installer (2.9 MB)
@mainWeb_1009_a
#All platforms (zip, 3.9 MB)
#All platforms (zip, 4.0 MB)
@mainWeb_1010_a
全てダウンロード
...
...
@@ -3179,268 +3179,268 @@ See what this database can do and how to use these features.
#Performance Comparison
@performance_1002_a
#Application Profiling
#PolePosition Benchmark
@performance_1003_a
#Application Profiling
@performance_1004_a
#Performance Tuning
@performance_1004_h2
@performance_1005_h2
#Performance Comparison
@performance_1005_p
@performance_1006_p
#In most cases H2 is a lot faster than all other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer.
@performance_1006_h3
@performance_1007_h3
#Embedded
@performance_1007_th
@performance_1008_th
#Test Case
@performance_1008_th
@performance_1009_th
#Unit
@performance_1009_th
@performance_1010_th
H2
@performance_1010_th
@performance_1011_th
HSQLDB
@performance_1011_th
@performance_1012_th
Derby
@performance_1012_td
#Simple: Init
@performance_1013_td
#ms
#Simple: Init
@performance_1014_td
#375
#ms
@performance_1015_td
#578
#375
@performance_1016_td
#2797
#578
@performance_1017_td
#Simple: Query (random)
#2797
@performance_1018_td
#ms
#Simple: Query (random)
@performance_1019_td
#250
#ms
@performance_1020_td
#344
#250
@performance_1021_td
#1563
#344
@performance_1022_td
#Simple: Query (sequential)
#1563
@performance_1023_td
#ms
#Simple: Query (sequential)
@performance_1024_td
#171
#ms
@performance_1025_td
#250
#171
@performance_1026_td
#1469
#250
@performance_1027_td
#Simple: Update (random)
#1469
@performance_1028_td
#ms
#Simple: Update (random)
@performance_1029_td
#641
#ms
@performance_1030_td
#1609
#641
@performance_1031_td
#19265
#1609
@performance_1032_td
#Simple: Delete (sequential)
#19265
@performance_1033_td
#ms
#Simple: Delete (sequential)
@performance_1034_td
#172
#ms
@performance_1035_td
#516
#172
@performance_1036_td
#6797
#516
@performance_1037_td
#Simple: Memory Usage
#6797
@performance_1038_td
#MB
#Simple: Memory Usage
@performance_1039_td
#14
#MB
@performance_1040_td
#12
#14
@performance_1041_td
#12
@performance_1042_td
#BenchA: Init
#12
@performance_1043_td
#ms
#BenchA: Init
@performance_1044_td
#391
#ms
@performance_1045_td
#500
#391
@performance_1046_td
#3750
#500
@performance_1047_td
#BenchA: Transactions
#3750
@performance_1048_td
#ms
#BenchA: Transactions
@performance_1049_td
#5468
#ms
@performance_1050_td
#2468
#5468
@performance_1051_td
#16250
#2468
@performance_1052_td
#BenchA: Memory Usage
#16250
@performance_1053_td
#MB
#BenchA: Memory Usage
@performance_1054_td
#14
#MB
@performance_1055_td
#15
#14
@performance_1056_td
#9
#15
@performance_1057_td
#BenchB: Init
#9
@performance_1058_td
#ms
#BenchB: Init
@performance_1059_td
#1281
#ms
@performance_1060_td
#2391
#1281
@performance_1061_td
#14938
#2391
@performance_1062_td
#BenchB: Transactions
#14938
@performance_1063_td
#ms
#BenchB: Transactions
@performance_1064_td
#2094
#ms
@performance_1065_td
#1140
#2094
@performance_1066_td
#3828
#1140
@performance_1067_td
#BenchB: Memory Usage
#3828
@performance_1068_td
#MB
#BenchB: Memory Usage
@performance_1069_td
16
#MB
@performance_1070_td
#11
16
@performance_1071_td
#9
#11
@performance_1072_td
#BenchC: Init
#9
@performance_1073_td
#ms
#BenchC: Init
@performance_1074_td
#984
#ms
@performance_1075_td
#547
#984
@performance_1076_td
#5250
#547
@performance_1077_td
#BenchC: Transactions
#5250
@performance_1078_td
#ms
#BenchC: Transactions
@performance_1079_td
#2860
#ms
@performance_1080_td
#58219
#2860
@performance_1081_td
#11204
#58219
@performance_1082_td
#BenchC: Memory Usage
#11204
@performance_1083_td
#MB
#BenchC: Memory Usage
@performance_1084_td
#19
#MB
@performance_1085_td
#19
@performance_1086_td
#9
#19
@performance_1087_td
#Executed Statements
#9
@performance_1088_td
##
#Executed Statements
@performance_1089_td
#594255
##
@performance_1090_td
#594255
...
...
@@ -3449,382 +3449,382 @@ Derby
#594255
@performance_1092_td
#Total Time
#594255
@performance_1093_td
#ms
#Total Time
@performance_1094_td
#14687
#ms
@performance_1095_td
#68562
#14687
@performance_1096_td
#87111
#68562
@performance_1097_td
#Statement per Second
#87111
@performance_1098_td
##
#Statement per Second
@performance_1099_td
#40461
##
@performance_1100_td
#8667
#40461
@performance_1101_td
#8667
@performance_1102_td
#6821
@performance_1102_h3
@performance_1103_h3
#Client-Server
@performance_1103_th
@performance_1104_th
#Test Case
@performance_1104_th
@performance_1105_th
#Unit
@performance_1105_th
@performance_1106_th
H2
@performance_1106_th
@performance_1107_th
HSQLDB
@performance_1107_th
@performance_1108_th
Derby
@performance_1108_th
@performance_1109_th
PostgreSQL
@performance_1109_th
@performance_1110_th
MySQL
@performance_1110_td
@performance_1111_td
#Simple: Init
@performance_1111_td
@performance_1112_td
#ms
@performance_1112_td
@performance_1113_td
#3047
@performance_1113_td
@performance_1114_td
#2547
@performance_1114_td
@performance_1115_td
#6907
@performance_1115_td
@performance_1116_td
#4234
@performance_1116_td
@performance_1117_td
#3594
@performance_1117_td
@performance_1118_td
#Simple: Query (random)
@performance_1118_td
@performance_1119_td
#ms
@performance_1119_td
@performance_1120_td
#3547
@performance_1120_td
@performance_1121_td
#2641
@performance_1121_td
@performance_1122_td
#8781
@performance_1122_td
@performance_1123_td
#5375
@performance_1123_td
@performance_1124_td
#3140
@performance_1124_td
@performance_1125_td
#Simple: Query (sequential)
@performance_1125_td
@performance_1126_td
#ms
@performance_1126_td
@performance_1127_td
#3390
@performance_1127_td
@performance_1128_td
#2531
@performance_1128_td
@performance_1129_td
#8859
@performance_1129_td
@performance_1130_td
#4906
@performance_1130_td
@performance_1131_td
#3016
@performance_1131_td
@performance_1132_td
#Simple: Update (random)
@performance_1132_td
@performance_1133_td
#ms
@performance_1133_td
@performance_1134_td
#3235
@performance_1134_td
@performance_1135_td
#3531
@performance_1135_td
@performance_1136_td
#22344
@performance_1136_td
@performance_1137_td
#5828
@performance_1137_td
@performance_1138_td
#5187
@performance_1138_td
@performance_1139_td
#Simple: Delete (sequential)
@performance_1139_td
@performance_1140_td
#ms
@performance_1140_td
#1421
@performance_1141_td
#1235
#1421
@performance_1142_td
#8219
#1235
@performance_1143_td
#2484
#8219
@performance_1144_td
#1829
#2484
@performance_1145_td
#Simple: Memory Usage
#1829
@performance_1146_td
#MB
#Simple: Memory Usage
@performance_1147_td
#15
#MB
@performance_1148_td
#10
#15
@performance_1149_td
#15
#10
@performance_1150_td
#0
#15
@performance_1151_td
#0
@performance_1152_td
#BenchA: Init
#0
@performance_1153_td
#ms
#BenchA: Init
@performance_1154_td
#2687
#ms
@performance_1155_td
#2343
#2687
@performance_1156_td
#6000
#2343
@performance_1157_td
#4000
#6000
@performance_1158_td
#4000
@performance_1159_td
#BenchA: Transactions
#4000
@performance_1160_td
#ms
#BenchA: Transactions
@performance_1161_td
#12938
#ms
@performance_1162_td
#9579
#12938
@performance_1163_td
#26610
#9579
@performance_1164_td
#16250
#26610
@performance_1165_td
#10782
#16250
@performance_1166_td
#BenchA: Memory Usage
#10782
@performance_1167_td
#MB
#BenchA: Memory Usage
@performance_1168_td
#15
#MB
@performance_1169_td
16
#15
@performance_1170_td
#10
16
@performance_1171_td
#0
#10
@performance_1172_td
#0
@performance_1173_td
#BenchB: Init
#0
@performance_1174_td
#ms
#BenchB: Init
@performance_1175_td
#9641
#ms
@performance_1176_td
#10094
#9641
@performance_1177_td
#28282
#10094
@performance_1178_td
#17468
#28282
@performance_1179_td
#11344
#17468
@performance_1180_td
#BenchB: Transactions
#11344
@performance_1181_td
#ms
#BenchB: Transactions
@performance_1182_td
#3984
#ms
@performance_1183_td
#3312
#3984
@performance_1184_td
#6671
#3312
@performance_1185_td
#7797
#6671
@performance_1186_td
#3375
#7797
@performance_1187_td
#BenchB: Memory Usage
#3375
@performance_1188_td
#MB
#BenchB: Memory Usage
@performance_1189_td
16
#MB
@performance_1190_td
#13
16
@performance_1191_td
#8
#13
@performance_1192_td
#0
#8
@performance_1193_td
#0
@performance_1194_td
#BenchC: Init
#0
@performance_1195_td
#ms
#BenchC: Init
@performance_1196_td
#2031
#ms
@performance_1197_td
#1516
#2031
@performance_1198_td
#7391
#1516
@performance_1199_td
#2297
#7391
@performance_1200_td
#3406
#2297
@performance_1201_td
#BenchC: Transactions
#3406
@performance_1202_td
#ms
#BenchC: Transactions
@performance_1203_td
#9750
#ms
@performance_1204_td
#58734
#9750
@performance_1205_td
#20937
#58734
@performance_1206_td
#11172
#20937
@performance_1207_td
#7469
#11172
@performance_1208_td
#BenchC: Memory Usage
#7469
@performance_1209_td
#MB
#BenchC: Memory Usage
@performance_1210_td
#20
#MB
@performance_1211_td
#15
#20
@performance_1212_td
#14
#15
@performance_1213_td
#0
#14
@performance_1214_td
#0
@performance_1215_td
#Executed Statements
#0
@performance_1216_td
##
#Executed Statements
@performance_1217_td
#594255
##
@performance_1218_td
#594255
...
...
@@ -3839,537 +3839,540 @@ MySQL
#594255
@performance_1222_td
#Total Time
#594255
@performance_1223_td
#ms
#Total Time
@performance_1224_td
#55671
#ms
@performance_1225_td
#98063
#55671
@performance_1226_td
#151001
#98063
@performance_1227_td
#81811
#151001
@performance_1228_td
#57142
#81811
@performance_1229_td
#Statement per Second
#57142
@performance_1230_td
##
#Statement per Second
@performance_1231_td
#10674
##
@performance_1232_td
#6059
#10674
@performance_1233_td
#3935
#6059
@performance_1234_td
#7263
#3935
@performance_1235_td
#7263
@performance_1236_td
#10399
@performance_1236_h3
@performance_1237_h3
#Benchmark Results and Comments
@performance_1237_h4
@performance_1238_h4
H2
@performance_1238_p
@performance_1239_p
#Version 1.0 (2007-09-15) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol: The engine waits 20 ms after opening a database to ensure the database files are not opened by another process.
@performance_1239_h4
@performance_1240_h4
HSQLDB
@performance_1240_p
@performance_1241_p
#Version 1.8.0.8 was used for the test. Cached tables are used in this test (hsqldb.default_table_type=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC: Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join:
@performance_1241_p
@performance_1242_p
#The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. A disadvantage in HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the database is created whenever the database is opened or closed.
@performance_1242_h4
@performance_1243_h4
Derby
@performance_1243_p
@performance_1244_p
#Version 10.3.1.4 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will not be easy for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified: Leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby.
@performance_1244_h4
@performance_1245_h4
PostgreSQL
@performance_1245_p
@performance_1246_p
#Version 8.1.4 was used for the test. The following options where changed in postgresql.conf: fsync = off, commit_delay = 1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
@performance_1246_h4
@performance_1247_h4
MySQL
@performance_1247_p
@performance_1248_p
#Version 5.0.22 was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
@performance_1248_h4
@performance_1249_h4
#Firebird
@performance_1249_p
@performance_1250_p
#Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome.
@performance_1250_h4
@performance_1251_h4
#Why Oracle / MS SQL Server / DB2 are Not Listed
@performance_1251_p
@performance_1252_p
#The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions.
@performance_1252_h3
@performance_1253_h3
#About this Benchmark
@performance_1253_h4
@performance_1254_h4
#Number of Connections
@performance_1254_p
@performance_1255_p
#This is mostly a single-connection benchmark. BenchB uses multiple connections, the other tests one connection.
@performance_1255_h4
@performance_1256_h4
#Real-World Tests
@performance_1256_p
@performance_1257_p
#Good benchmarks emulate real-world use cases. This benchmark includes 3 test cases: A simple test case with one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also: www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded.
@performance_1257_h4
@performance_1258_h4
#Comparing Embedded with Server Databases
@performance_1258_p
@performance_1259_p
#This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine than the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested.
@performance_1259_h4
@performance_1260_h4
#Test Platform
@performance_1260_p
@performance_1261_p
#This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5.
@performance_1261_h4
@performance_1262_h4
#Multiple Runs
@performance_1262_p
@performance_1263_p
#When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, the last run counts.
@performance_1263_h4
@performance_1264_h4
#Memory Usage
@performance_1264_p
@performance_1265_p
#It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved in databases by using a bigger in-memory cache, but there is only a limited amount of memory available on the system. HSQLDB tables are kept fully in memory by default, this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases.
@performance_1265_h4
@performance_1266_h4
#Delayed Operations
@performance_1266_p
@performance_1267_p
#Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially).
@performance_1267_h4
@performance_1268_h4
#Transaction Commit / Durability
@performance_1268_p
@performance_1269_p
#Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling fsync() slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used.
@performance_1269_h4
@performance_1270_h4
#Using Prepared Statements
@performance_1270_p
@performance_1271_p
#Wherever possible, the test cases use prepared statements.
@performance_1271_h4
@performance_1272_h4
#Currently Not Tested: Startup Time
@performance_1272_p
@performance_1273_p
#The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. That means the Open/Close time listed is for opening a connection if the database is already in use.
@performance_1273_h3
@performance_1274_h2
#PolePosition Benchmark
@performance_1274_p
@performance_1275_p
#The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o.
@performance_1275_th
@performance_1276_th
#Test Case
@performance_1276_th
@performance_1277_th
#Unit
@performance_1277_th
@performance_1278_th
H2
@performance_1278_th
@performance_1279_th
HSQLDB
@performance_1279_th
@performance_1280_th
MySQL
@performance_1280_td
@performance_1281_td
#Melbourne write
@performance_1281_td
@performance_1282_td
#ms
@performance_1282_td
@performance_1283_td
#369
@performance_1283_td
@performance_1284_td
#249
@performance_1284_td
@performance_1285_td
#2022
@performance_1285_td
@performance_1286_td
#Melbourne read
@performance_1286_td
@performance_1287_td
#ms
@performance_1287_td
@performance_1288_td
#47
@performance_1288_td
@performance_1289_td
#49
@performance_1289_td
@performance_1290_td
#93
@performance_1290_td
@performance_1291_td
#Melbourne read_hot
@performance_1291_td
@performance_1292_td
#ms
@performance_1292_td
@performance_1293_td
#24
@performance_1293_td
@performance_1294_td
#43
@performance_1294_td
@performance_1295_td
#95
@performance_1295_td
@performance_1296_td
#Melbourne delete
@performance_1296_td
@performance_1297_td
#ms
@performance_1297_td
@performance_1298_td
#147
@performance_1298_td
@performance_1299_td
#133
@performance_1299_td
@performance_1300_td
#176
@performance_1300_td
@performance_1301_td
#Sepang write
@performance_1301_td
@performance_1302_td
#ms
@performance_1302_td
@performance_1303_td
#965
@performance_1303_td
@performance_1304_td
#1201
@performance_1304_td
@performance_1305_td
#3213
@performance_1305_td
@performance_1306_td
#Sepang read
@performance_1306_td
@performance_1307_td
#ms
@performance_1307_td
@performance_1308_td
#765
@performance_1308_td
@performance_1309_td
#948
@performance_1309_td
@performance_1310_td
#3455
@performance_1310_td
@performance_1311_td
#Sepang read_hot
@performance_1311_td
@performance_1312_td
#ms
@performance_1312_td
@performance_1313_td
#789
@performance_1313_td
@performance_1314_td
#859
@performance_1314_td
@performance_1315_td
#3563
@performance_1315_td
@performance_1316_td
#Sepang delete
@performance_1316_td
@performance_1317_td
#ms
@performance_1317_td
@performance_1318_td
#1384
@performance_1318_td
@performance_1319_td
#1596
@performance_1319_td
@performance_1320_td
#6214
@performance_1320_td
@performance_1321_td
#Bahrain write
@performance_1321_td
@performance_1322_td
#ms
@performance_1322_td
@performance_1323_td
#1186
@performance_1323_td
@performance_1324_td
#1387
@performance_1324_td
@performance_1325_td
#6904
@performance_1325_td
@performance_1326_td
#Bahrain query_indexed_string
@performance_1326_td
@performance_1327_td
#ms
@performance_1327_td
@performance_1328_td
#336
@performance_1328_td
@performance_1329_td
#170
@performance_1329_td
@performance_1330_td
#693
@performance_1330_td
@performance_1331_td
#Bahrain query_string
@performance_1331_td
@performance_1332_td
#ms
@performance_1332_td
@performance_1333_td
#18064
@performance_1333_td
@performance_1334_td
#39703
@performance_1334_td
@performance_1335_td
#41243
@performance_1335_td
@performance_1336_td
#Bahrain query_indexed_int
@performance_1336_td
@performance_1337_td
#ms
@performance_1337_td
@performance_1338_td
#104
@performance_1338_td
@performance_1339_td
#134
@performance_1339_td
@performance_1340_td
#678
@performance_1340_td
@performance_1341_td
#Bahrain update
@performance_1341_td
@performance_1342_td
#ms
@performance_1342_td
@performance_1343_td
#191
@performance_1343_td
@performance_1344_td
#87
@performance_1344_td
@performance_1345_td
#159
@performance_1345_td
@performance_1346_td
#Bahrain delete
@performance_1346_td
@performance_1347_td
#ms
@performance_1347_td
@performance_1348_td
#1215
@performance_1348_td
@performance_1349_td
#729
@performance_1349_td
@performance_1350_td
#6812
@performance_1350_td
@performance_1351_td
#Imola retrieve
@performance_1351_td
@performance_1352_td
#ms
@performance_1352_td
@performance_1353_td
#198
@performance_1353_td
@performance_1354_td
#194
@performance_1354_td
@performance_1355_td
#4036
@performance_1355_td
@performance_1356_td
#Barcelona write
@performance_1356_td
@performance_1357_td
#ms
@performance_1357_td
@performance_1358_td
#413
@performance_1358_td
@performance_1359_td
#832
@performance_1359_td
@performance_1360_td
#3191
@performance_1360_td
@performance_1361_td
#Barcelona read
@performance_1361_td
@performance_1362_td
#ms
@performance_1362_td
@performance_1363_td
#119
@performance_1363_td
@performance_1364_td
#160
@performance_1364_td
@performance_1365_td
#1177
@performance_1365_td
@performance_1366_td
#Barcelona query
@performance_1366_td
@performance_1367_td
#ms
@performance_1367_td
@performance_1368_td
#20
@performance_1368_td
@performance_1369_td
#5169
@performance_1369_td
@performance_1370_td
#101
@performance_1370_td
@performance_1371_td
#Barcelona delete
@performance_1371_td
@performance_1372_td
#ms
@performance_1372_td
@performance_1373_td
#388
@performance_1373_td
@performance_1374_td
#319
@performance_1374_td
@performance_1375_td
#3287
@performance_1375_td
@performance_1376_td
#Total
@performance_1376_td
@performance_1377_td
#ms
@performance_1377_td
@performance_1378_td
#26724
@performance_1378_td
@performance_1379_td
#53962
@performance_1379_td
@performance_1380_td
#87112
@performance_1380_h2
@performance_1381_h2
#Application Profiling
@performance_1381_h3
@performance_1382_h3
#Analyze First
@performance_1382_p
@performance_1383_p
#Before trying to optimize the performance, it is important to know where the time is actually spent. The same is true for memory problems. Premature or 'blind' optimization should be avoided, as it is not an efficient way to solve the problem. There are various ways to analyze the application. In some situations it is possible to compare two implementations and use System.currentTimeMillis() to find out which one is faster. But this does not work for complex applications with many modules, and for memory problems. A very good tool to measure both the memory and the CPU is the <a href="http://www.yourkit.com">YourKit Java Profiler</a> . This tool is also used to optimize the performance and memory footprint of this database engine.
@performance_1383_h2
@performance_1384_h2
#Database Performance Tuning
@performance_1384_h3
@performance_1385_h3
#Virus Scanners
@performance_1385_p
@performance_1386_p
#Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine does never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow excluding file endings. Make sure files ending with .db are not scanned.
@performance_1386_h3
@performance_1387_h3
トレースオプションを使用する
@performance_1387_p
@performance_1388_p
#If the main performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see <a href="features.html#trace_options">Using the Trace Options</a> .
@performance_1388_h3
@performance_1389_h3
#Index Usage
@performance_1389_p
@performance_1390_p
#This database uses indexes to improve the performance of SELECT, UPDATE and DELETE statements. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are not used to order result sets: The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement.
@performance_1390_h3
@performance_1391_h3
#Optimizer
@performance_1391_p
@performance_1392_p
#This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated.
@performance_1392_h3
@performance_1393_h3
#Expression Optimization
@performance_1393_p
@performance_1394_p
#After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all.
@performance_1394_h3
@performance_1395_h3
#COUNT(*) Optimization
@performance_1395_p
@performance_1396_p
#If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table.
#When executing a query, at most one index per joined table can be used. If the same table is joined multiple times, for each join only one index is used. Example: for the query SELECT * FROM TEST T1, TEST T2 WHERE T1.NAME='A' AND T2.ID=T1.ID, two index can be used, in this case the index on NAME for T1 and the index on ID for T2.
@performance_1398_p
@performance_1399_p
#If a table has multiple indexes, sometimes more than one index could be used. Example: if there is a table TEST(ID, NAME, FIRSTNAME) and an index on each column, then two indexes could be used for the query SELECT * FROM TEST WHERE NAME='A' AND FIRSTNAME='B', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of values in a column. A selectivity of 100 means each value appears only once, and a selectivity of 1 means the same value appears in many or most rows. For the query above, the index on NAME should be used if the table contains more distinct names than first names.
@performance_1399_p
@performance_1400_p
#The SQL statement ANALYZE can be used to automatically estimate the selectivity of the columns in the tables. This command should be run from time to time to improve the query plans generated by the optimizer.
もしポートが他のアプリケーションによって使用されている場合は、H2コンソールを異なったポートで起動したいはずです。これは、.h2.server.properties.ファイル内のポートを変更することにより実行できます。このファイルはユーザディレクトリ内に格納されています (Windowsでは通常、"Documents and Settings/<ユーザ名>")。関連する項目はwebPortです。
サーバーを起動するとローカルのホームディレクトリに .h2.server.properties と呼ばれるファイル構成が作成されます。Windowsのインストールでは、このファイルは will be in the directory C:\Documents and Settings\[ユーザ名]のディレクトリ内にあります。このファイルはアプリケーションのセッティングに含まれています。
テーブル名やカラム名は、ツリー内のテーブル名、カラム名をクリックすることによってスクリプトにインサートすることができます。クエリが空の時にテーブルをクリックすると、 'SELECT * FROM ...' も同様に追加されます。 クエリを入力している間、使用されているテーブルはツリー内で自動的に拡張されます。例えば、 'SELECT * FROM TEST T WHERE T.' と入力すると、ツリー内のTESTテーブルは自動的に拡張されます。
#To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code:
#To use the Lucene full text search, you need the Lucene library in the classpath. How his is done depends on the application; if you use the H2 Console, you can add the Lucene jar file to the the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene full text search in a database, call:
@tutorial_1142_p
@tutorial_1143_p
#You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using:
#This database supports user defined variables. Variables start with @ and can be used whereever expressions or parameters are used. Variables not persisted and session scoped, that means only visible for the session where they are defined. A value is usually assigned using the SET command:
@tutorial_1148_p
#It is also possible to change a value using the SET() method. This is useful in queries:
@tutorial_1149_p
#Variables that are not set evaluate to NULL. The data type of a user defined variable is the data type of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. There are no restrictions on the assigned values, large objects (LOBs) are supported as well.
@~performance_1004_h2
#Performance Comparison
@~performance_1005_p
#In most cases H2 is a lot faster than all other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer.
@~performance_1006_h3
#Embedded
@~performance_1007_th
#Test Case
@~performance_1012_td
#Simple: Init
@~performance_1102_h3
#Client-Server
@~performance_1103_th
#Test Case
@~performance_1110_td
#Simple: Init
@~performance_1236_h3
#Benchmark Results and Comments
@~performance_1237_h4
H2
@~performance_1238_p
#Version 1.0 (2007-09-15) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol: The engine waits 20 ms after opening a database to ensure the database files are not opened by another process.
@~performance_1239_h4
HSQLDB
@~performance_1240_p
#Version 1.8.0.8 was used for the test. Cached tables are used in this test (hsqldb.default_table_type=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC: Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join:
@~performance_1242_h4
Derby
@~performance_1243_p
#Version 10.3.1.4 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will not be easy for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified: Leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby.
@~performance_1244_h4
PostgreSQL
@~performance_1245_p
#Version 8.1.4 was used for the test. The following options where changed in postgresql.conf: fsync = off, commit_delay = 1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
@~performance_1246_h4
MySQL
@~performance_1247_p
#Version 5.0.22 was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
@~performance_1248_h4
#Firebird
@~performance_1249_p
#Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome.
@~performance_1250_h4
#Why Oracle / MS SQL Server / DB2 are Not Listed
@~performance_1251_p
#The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions.
@~performance_1252_h3
#About this Benchmark
@~performance_1253_h4
#Number of Connections
@~performance_1254_p
#This is mostly a single-connection benchmark. BenchB uses multiple connections, the other tests one connection.
@~performance_1255_h4
#Real-World Tests
@~performance_1256_p
#Good benchmarks emulate real-world use cases. This benchmark includes 3 test cases: A simple test case with one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also: www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded.
@~performance_1257_h4
#Comparing Embedded with Server Databases
@~performance_1258_p
#This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine than the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested.
@~performance_1259_h4
#Test Platform
@~performance_1260_p
#This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5.
@~performance_1261_h4
#Multiple Runs
@~performance_1262_p
#When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, the last run counts.
@~performance_1263_h4
#Memory Usage
@~performance_1264_p
#It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved in databases by using a bigger in-memory cache, but there is only a limited amount of memory available on the system. HSQLDB tables are kept fully in memory by default, this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases.
@~performance_1265_h4
#Delayed Operations
@~performance_1266_p
#Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially).
@~performance_1267_h4
#Transaction Commit / Durability
@~performance_1268_p
#Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling fsync() slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used.
@~performance_1269_h4
#Using Prepared Statements
@~performance_1270_p
#Wherever possible, the test cases use prepared statements.
@~performance_1271_h4
#Currently Not Tested: Startup Time
@~performance_1272_p
#The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. That means the Open/Close time listed is for opening a connection if the database is already in use.
@~performance_1273_h3
#PolePosition Benchmark
@~performance_1274_p
#The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o.
@~performance_1275_th
#Test Case
@~performance_1280_td
#Melbourne write
@~performance_1380_h2
#Application Profiling
@~performance_1381_h3
#Analyze First
@~performance_1382_p
#Before trying to optimize the performance, it is important to know where the time is actually spent. The same is true for memory problems. Premature or 'blind' optimization should be avoided, as it is not an efficient way to solve the problem. There are various ways to analyze the application. In some situations it is possible to compare two implementations and use System.currentTimeMillis() to find out which one is faster. But this does not work for complex applications with many modules, and for memory problems. A very good tool to measure both the memory and the CPU is the <a href="http://www.yourkit.com">YourKit Java Profiler</a> . This tool is also used to optimize the performance and memory footprint of this database engine.
@~performance_1383_h2
#Database Performance Tuning
@~performance_1384_h3
#Virus Scanners
@~performance_1385_p
#Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine does never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow excluding file endings. Make sure files ending with .db are not scanned.
@~performance_1386_h3
トレースオプションを使用する
@~performance_1387_p
#If the main performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see <a href="features.html#trace_options">Using the Trace Options</a> .
@~performance_1388_h3
#Index Usage
@~performance_1389_p
#This database uses indexes to improve the performance of SELECT, UPDATE and DELETE statements. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are not used to order result sets: The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement.
@~performance_1390_h3
#Optimizer
@~performance_1391_p
#This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated.
@~performance_1392_h3
#Expression Optimization
@~performance_1393_p
#After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all.
@~performance_1394_h3
#COUNT(*) Optimization
@~performance_1395_p
#If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table.
#When executing a query, at most one index per joined table can be used. If the same table is joined multiple times, for each join only one index is used. Example: for the query SELECT * FROM TEST T1, TEST T2 WHERE T1.NAME='A' AND T2.ID=T1.ID, two index can be used, in this case the index on NAME for T1 and the index on ID for T2.
もしポートが他のアプリケーションによって使用されている場合は、H2コンソールを異なったポートで起動したいはずです。これは、.h2.server.properties.ファイル内のポートを変更することにより実行できます。このファイルはユーザディレクトリ内に格納されています (Windowsでは通常、"Documents and Settings/<ユーザ名>")。関連する項目はwebPortです。
サーバーを起動するとローカルのホームディレクトリに .h2.server.properties と呼ばれるファイル構成が作成されます。Windowsのインストールでは、このファイルは will be in the directory C:\Documents and Settings\[ユーザ名]のディレクトリ内にあります。このファイルはアプリケーションのセッティングに含まれています。
テーブル名やカラム名は、ツリー内のテーブル名、カラム名をクリックすることによってスクリプトにインサートすることができます。クエリが空の時にテーブルをクリックすると、 'SELECT * FROM ...' も同様に追加されます。 クエリを入力している間、使用されているテーブルはツリー内で自動的に拡張されます。例えば、 'SELECT * FROM TEST T WHERE T.' と入力すると、ツリー内のTESTテーブルは自動的に拡張されます。
#To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code:
#To use the Lucene full text search, you need the Lucene library in the classpath. How his is done depends on the application; if you use the H2 Console, you can add the Lucene jar file to the the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene full text search in a database, call:
@@ -1021,8 +1021,8 @@ mainWeb_1004_li=Embedded, Server and Cluster modes
mainWeb_1005_li=JDBC and (partial) ODBC API; Web Client application
mainWeb_1006_h3=Download
mainWeb_1007_td=Version 1.0.65 (2008-01-18)\:
mainWeb_1008_a=Windows Installer (2.8 MB)
mainWeb_1009_a=All platforms (zip, 3.9 MB)
mainWeb_1008_a=Windows Installer (2.9 MB)
mainWeb_1009_a=All platforms (zip, 4.0 MB)
mainWeb_1010_a=All Downloads
mainWeb_1011_td=
mainWeb_1012_h3=Support
...
...
@@ -1056,404 +1056,405 @@ main_1006_a=Features
main_1007_p=See what this database can do and how to use these features.
performance_1000_h1=Performance
performance_1001_a=Performance Comparison
performance_1002_a=Application Profiling
performance_1003_a=Performance Tuning
performance_1004_h2=Performance Comparison
performance_1005_p=In most cases H2 is a lot faster than all other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer.
performance_1006_h3=Embedded
performance_1007_th=Test Case
performance_1008_th=Unit
performance_1009_th=H2
performance_1010_th=HSQLDB
performance_1011_th=Derby
performance_1012_td=Simple\:Init
performance_1013_td=ms
performance_1014_td=375
performance_1015_td=578
performance_1016_td=2797
performance_1017_td=Simple\:Query (random)
performance_1018_td=ms
performance_1019_td=250
performance_1020_td=344
performance_1021_td=1563
performance_1022_td=Simple\:Query (sequential)
performance_1023_td=ms
performance_1024_td=171
performance_1025_td=250
performance_1026_td=1469
performance_1027_td=Simple\:Update (random)
performance_1028_td=ms
performance_1029_td=641
performance_1030_td=1609
performance_1031_td=19265
performance_1032_td=Simple\:Delete (sequential)
performance_1033_td=ms
performance_1034_td=172
performance_1035_td=516
performance_1036_td=6797
performance_1037_td=Simple\:Memory Usage
performance_1038_td=MB
performance_1039_td=14
performance_1040_td=12
performance_1002_a=PolePosition Benchmark
performance_1003_a=Application Profiling
performance_1004_a=Performance Tuning
performance_1005_h2=Performance Comparison
performance_1006_p=In most cases H2 is a lot faster than all other (open source and not open source) database engines. Please note this is mostly a single connection benchmark run on one computer.
performance_1007_h3=Embedded
performance_1008_th=Test Case
performance_1009_th=Unit
performance_1010_th=H2
performance_1011_th=HSQLDB
performance_1012_th=Derby
performance_1013_td=Simple\:Init
performance_1014_td=ms
performance_1015_td=375
performance_1016_td=578
performance_1017_td=2797
performance_1018_td=Simple\:Query (random)
performance_1019_td=ms
performance_1020_td=250
performance_1021_td=344
performance_1022_td=1563
performance_1023_td=Simple\:Query (sequential)
performance_1024_td=ms
performance_1025_td=171
performance_1026_td=250
performance_1027_td=1469
performance_1028_td=Simple\:Update (random)
performance_1029_td=ms
performance_1030_td=641
performance_1031_td=1609
performance_1032_td=19265
performance_1033_td=Simple\:Delete (sequential)
performance_1034_td=ms
performance_1035_td=172
performance_1036_td=516
performance_1037_td=6797
performance_1038_td=Simple\:Memory Usage
performance_1039_td=MB
performance_1040_td=14
performance_1041_td=12
performance_1042_td=BenchA\:Init
performance_1043_td=ms
performance_1044_td=391
performance_1045_td=500
performance_1046_td=3750
performance_1047_td=BenchA\:Transactions
performance_1048_td=ms
performance_1049_td=5468
performance_1050_td=2468
performance_1051_td=16250
performance_1052_td=BenchA\:Memory Usage
performance_1053_td=MB
performance_1054_td=14
performance_1055_td=15
performance_1056_td=9
performance_1057_td=BenchB\:Init
performance_1058_td=ms
performance_1059_td=1281
performance_1060_td=2391
performance_1061_td=14938
performance_1062_td=BenchB\:Transactions
performance_1063_td=ms
performance_1064_td=2094
performance_1065_td=1140
performance_1066_td=3828
performance_1067_td=BenchB\:Memory Usage
performance_1068_td=MB
performance_1069_td=16
performance_1070_td=11
performance_1071_td=9
performance_1072_td=BenchC\:Init
performance_1073_td=ms
performance_1074_td=984
performance_1075_td=547
performance_1076_td=5250
performance_1077_td=BenchC\:Transactions
performance_1078_td=ms
performance_1079_td=2860
performance_1080_td=58219
performance_1081_td=11204
performance_1082_td=BenchC\:Memory Usage
performance_1083_td=MB
performance_1084_td=19
performance_1042_td=12
performance_1043_td=BenchA\:Init
performance_1044_td=ms
performance_1045_td=391
performance_1046_td=500
performance_1047_td=3750
performance_1048_td=BenchA\:Transactions
performance_1049_td=ms
performance_1050_td=5468
performance_1051_td=2468
performance_1052_td=16250
performance_1053_td=BenchA\:Memory Usage
performance_1054_td=MB
performance_1055_td=14
performance_1056_td=15
performance_1057_td=9
performance_1058_td=BenchB\:Init
performance_1059_td=ms
performance_1060_td=1281
performance_1061_td=2391
performance_1062_td=14938
performance_1063_td=BenchB\:Transactions
performance_1064_td=ms
performance_1065_td=2094
performance_1066_td=1140
performance_1067_td=3828
performance_1068_td=BenchB\:Memory Usage
performance_1069_td=MB
performance_1070_td=16
performance_1071_td=11
performance_1072_td=9
performance_1073_td=BenchC\:Init
performance_1074_td=ms
performance_1075_td=984
performance_1076_td=547
performance_1077_td=5250
performance_1078_td=BenchC\:Transactions
performance_1079_td=ms
performance_1080_td=2860
performance_1081_td=58219
performance_1082_td=11204
performance_1083_td=BenchC\:Memory Usage
performance_1084_td=MB
performance_1085_td=19
performance_1086_td=9
performance_1087_td=Executed Statements
performance_1088_td=\#
performance_1089_td=594255
performance_1086_td=19
performance_1087_td=9
performance_1088_td=Executed Statements
performance_1089_td=\#
performance_1090_td=594255
performance_1091_td=594255
performance_1092_td=Total Time
performance_1093_td=ms
performance_1094_td=14687
performance_1095_td=68562
performance_1096_td=87111
performance_1097_td=Statement per Second
performance_1098_td=\#
performance_1099_td=40461
performance_1100_td=8667
performance_1101_td=6821
performance_1102_h3=Client-Server
performance_1103_th=Test Case
performance_1104_th=Unit
performance_1105_th=H2
performance_1106_th=HSQLDB
performance_1107_th=Derby
performance_1108_th=PostgreSQL
performance_1109_th=MySQL
performance_1110_td=Simple\:Init
performance_1111_td=ms
performance_1112_td=3047
performance_1113_td=2547
performance_1114_td=6907
performance_1115_td=4234
performance_1116_td=3594
performance_1117_td=Simple\:Query (random)
performance_1118_td=ms
performance_1119_td=3547
performance_1120_td=2641
performance_1121_td=8781
performance_1122_td=5375
performance_1123_td=3140
performance_1124_td=Simple\:Query (sequential)
performance_1125_td=ms
performance_1126_td=3390
performance_1127_td=2531
performance_1128_td=8859
performance_1129_td=4906
performance_1130_td=3016
performance_1131_td=Simple\:Update (random)
performance_1132_td=ms
performance_1133_td=3235
performance_1134_td=3531
performance_1135_td=22344
performance_1136_td=5828
performance_1137_td=5187
performance_1138_td=Simple\:Delete (sequential)
performance_1139_td=ms
performance_1140_td=1421
performance_1141_td=1235
performance_1142_td=8219
performance_1143_td=2484
performance_1144_td=1829
performance_1145_td=Simple\:Memory Usage
performance_1146_td=MB
performance_1147_td=15
performance_1148_td=10
performance_1149_td=15
performance_1150_td=0
performance_1092_td=594255
performance_1093_td=Total Time
performance_1094_td=ms
performance_1095_td=14687
performance_1096_td=68562
performance_1097_td=87111
performance_1098_td=Statement per Second
performance_1099_td=\#
performance_1100_td=40461
performance_1101_td=8667
performance_1102_td=6821
performance_1103_h3=Client-Server
performance_1104_th=Test Case
performance_1105_th=Unit
performance_1106_th=H2
performance_1107_th=HSQLDB
performance_1108_th=Derby
performance_1109_th=PostgreSQL
performance_1110_th=MySQL
performance_1111_td=Simple\:Init
performance_1112_td=ms
performance_1113_td=3047
performance_1114_td=2547
performance_1115_td=6907
performance_1116_td=4234
performance_1117_td=3594
performance_1118_td=Simple\:Query (random)
performance_1119_td=ms
performance_1120_td=3547
performance_1121_td=2641
performance_1122_td=8781
performance_1123_td=5375
performance_1124_td=3140
performance_1125_td=Simple\:Query (sequential)
performance_1126_td=ms
performance_1127_td=3390
performance_1128_td=2531
performance_1129_td=8859
performance_1130_td=4906
performance_1131_td=3016
performance_1132_td=Simple\:Update (random)
performance_1133_td=ms
performance_1134_td=3235
performance_1135_td=3531
performance_1136_td=22344
performance_1137_td=5828
performance_1138_td=5187
performance_1139_td=Simple\:Delete (sequential)
performance_1140_td=ms
performance_1141_td=1421
performance_1142_td=1235
performance_1143_td=8219
performance_1144_td=2484
performance_1145_td=1829
performance_1146_td=Simple\:Memory Usage
performance_1147_td=MB
performance_1148_td=15
performance_1149_td=10
performance_1150_td=15
performance_1151_td=0
performance_1152_td=BenchA\:Init
performance_1153_td=ms
performance_1154_td=2687
performance_1155_td=2343
performance_1156_td=6000
performance_1157_td=4000
performance_1152_td=0
performance_1153_td=BenchA\:Init
performance_1154_td=ms
performance_1155_td=2687
performance_1156_td=2343
performance_1157_td=6000
performance_1158_td=4000
performance_1159_td=BenchA\:Transactions
performance_1160_td=ms
performance_1161_td=12938
performance_1162_td=9579
performance_1163_td=26610
performance_1164_td=16250
performance_1165_td=10782
performance_1166_td=BenchA\:Memory Usage
performance_1167_td=MB
performance_1168_td=15
performance_1169_td=16
performance_1170_td=10
performance_1171_td=0
performance_1159_td=4000
performance_1160_td=BenchA\:Transactions
performance_1161_td=ms
performance_1162_td=12938
performance_1163_td=9579
performance_1164_td=26610
performance_1165_td=16250
performance_1166_td=10782
performance_1167_td=BenchA\:Memory Usage
performance_1168_td=MB
performance_1169_td=15
performance_1170_td=16
performance_1171_td=10
performance_1172_td=0
performance_1173_td=BenchB\:Init
performance_1174_td=ms
performance_1175_td=9641
performance_1176_td=10094
performance_1177_td=28282
performance_1178_td=17468
performance_1179_td=11344
performance_1180_td=BenchB\:Transactions
performance_1181_td=ms
performance_1182_td=3984
performance_1183_td=3312
performance_1184_td=6671
performance_1185_td=7797
performance_1186_td=3375
performance_1187_td=BenchB\:Memory Usage
performance_1188_td=MB
performance_1189_td=16
performance_1190_td=13
performance_1191_td=8
performance_1192_td=0
performance_1173_td=0
performance_1174_td=BenchB\:Init
performance_1175_td=ms
performance_1176_td=9641
performance_1177_td=10094
performance_1178_td=28282
performance_1179_td=17468
performance_1180_td=11344
performance_1181_td=BenchB\:Transactions
performance_1182_td=ms
performance_1183_td=3984
performance_1184_td=3312
performance_1185_td=6671
performance_1186_td=7797
performance_1187_td=3375
performance_1188_td=BenchB\:Memory Usage
performance_1189_td=MB
performance_1190_td=16
performance_1191_td=13
performance_1192_td=8
performance_1193_td=0
performance_1194_td=BenchC\:Init
performance_1195_td=ms
performance_1196_td=2031
performance_1197_td=1516
performance_1198_td=7391
performance_1199_td=2297
performance_1200_td=3406
performance_1201_td=BenchC\:Transactions
performance_1202_td=ms
performance_1203_td=9750
performance_1204_td=58734
performance_1205_td=20937
performance_1206_td=11172
performance_1207_td=7469
performance_1208_td=BenchC\:Memory Usage
performance_1209_td=MB
performance_1210_td=20
performance_1211_td=15
performance_1212_td=14
performance_1213_td=0
performance_1194_td=0
performance_1195_td=BenchC\:Init
performance_1196_td=ms
performance_1197_td=2031
performance_1198_td=1516
performance_1199_td=7391
performance_1200_td=2297
performance_1201_td=3406
performance_1202_td=BenchC\:Transactions
performance_1203_td=ms
performance_1204_td=9750
performance_1205_td=58734
performance_1206_td=20937
performance_1207_td=11172
performance_1208_td=7469
performance_1209_td=BenchC\:Memory Usage
performance_1210_td=MB
performance_1211_td=20
performance_1212_td=15
performance_1213_td=14
performance_1214_td=0
performance_1215_td=Executed Statements
performance_1216_td=\#
performance_1217_td=594255
performance_1215_td=0
performance_1216_td=Executed Statements
performance_1217_td=\#
performance_1218_td=594255
performance_1219_td=594255
performance_1220_td=594255
performance_1221_td=594255
performance_1222_td=Total Time
performance_1223_td=ms
performance_1224_td=55671
performance_1225_td=98063
performance_1226_td=151001
performance_1227_td=81811
performance_1228_td=57142
performance_1229_td=Statement per Second
performance_1230_td=\#
performance_1231_td=10674
performance_1232_td=6059
performance_1233_td=3935
performance_1234_td=7263
performance_1235_td=10399
performance_1236_h3=Benchmark Results and Comments
performance_1237_h4=H2
performance_1238_p=Version 1.0 (2007-09-15) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol\:The engine waits 20 ms after opening a database to ensure the database files are not opened by another process.
performance_1239_h4=HSQLDB
performance_1240_p=Version 1.8.0.8 was used for the test. Cached tables are used in this test (hsqldb.default_table_type\=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC\:Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join\:
performance_1241_p=The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. A disadvantage in HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the database is created whenever the database is opened or closed.
performance_1242_h4=Derby
performance_1243_p=Version 10.3.1.4 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will not be easy for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified\:Leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby.
performance_1244_h4=PostgreSQL
performance_1245_p=Version 8.1.4 was used for the test. The following options where changed in postgresql.conf\:fsync \=off, commit_delay \=1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
performance_1246_h4=MySQL
performance_1247_p=Version 5.0.22 was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
performance_1248_h4=Firebird
performance_1249_p=Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome.
performance_1250_h4=Why Oracle / MS SQL Server / DB2 are Not Listed
performance_1251_p=The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions.
performance_1252_h3=About this Benchmark
performance_1253_h4=Number of Connections
performance_1254_p=This is mostly a single-connection benchmark. BenchB uses multiple connections, the other tests one connection.
performance_1255_h4=Real-World Tests
performance_1256_p=Good benchmarks emulate real-world use cases. This benchmark includes 3 test cases\:A simple test case with one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also\:www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded.
performance_1257_h4=Comparing Embedded with Server Databases
performance_1258_p=This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine than the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested.
performance_1259_h4=Test Platform
performance_1260_p=This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5.
performance_1261_h4=Multiple Runs
performance_1262_p=When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, the last run counts.
performance_1263_h4=Memory Usage
performance_1264_p=It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved in databases by using a bigger in-memory cache, but there is only a limited amount of memory available on the system. HSQLDB tables are kept fully in memory by default, this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases.
performance_1265_h4=Delayed Operations
performance_1266_p=Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially).
performance_1268_p=Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling fsync() slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used.
performance_1269_h4=Using Prepared Statements
performance_1270_p=Wherever possible, the test cases use prepared statements.
performance_1271_h4=Currently Not Tested\:Startup Time
performance_1272_p=The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. That means the Open/Close time listed is for opening a connection if the database is already in use.
performance_1273_h3=PolePosition Benchmark
performance_1274_p=The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o.
performance_1275_th=Test Case
performance_1276_th=Unit
performance_1277_th=H2
performance_1278_th=HSQLDB
performance_1279_th=MySQL
performance_1280_td=Melbourne write
performance_1281_td=ms
performance_1282_td=369
performance_1283_td=249
performance_1284_td=2022
performance_1285_td=Melbourne read
performance_1286_td=ms
performance_1287_td=47
performance_1288_td=49
performance_1289_td=93
performance_1290_td=Melbourne read_hot
performance_1291_td=ms
performance_1292_td=24
performance_1293_td=43
performance_1294_td=95
performance_1295_td=Melbourne delete
performance_1296_td=ms
performance_1297_td=147
performance_1298_td=133
performance_1299_td=176
performance_1300_td=Sepang write
performance_1301_td=ms
performance_1302_td=965
performance_1303_td=1201
performance_1304_td=3213
performance_1305_td=Sepang read
performance_1306_td=ms
performance_1307_td=765
performance_1308_td=948
performance_1309_td=3455
performance_1310_td=Sepang read_hot
performance_1311_td=ms
performance_1312_td=789
performance_1313_td=859
performance_1314_td=3563
performance_1315_td=Sepang delete
performance_1316_td=ms
performance_1317_td=1384
performance_1318_td=1596
performance_1319_td=6214
performance_1320_td=Bahrain write
performance_1321_td=ms
performance_1322_td=1186
performance_1323_td=1387
performance_1324_td=6904
performance_1325_td=Bahrain query_indexed_string
performance_1326_td=ms
performance_1327_td=336
performance_1328_td=170
performance_1329_td=693
performance_1330_td=Bahrain query_string
performance_1331_td=ms
performance_1332_td=18064
performance_1333_td=39703
performance_1334_td=41243
performance_1335_td=Bahrain query_indexed_int
performance_1336_td=ms
performance_1337_td=104
performance_1338_td=134
performance_1339_td=678
performance_1340_td=Bahrain update
performance_1341_td=ms
performance_1342_td=191
performance_1343_td=87
performance_1344_td=159
performance_1345_td=Bahrain delete
performance_1346_td=ms
performance_1347_td=1215
performance_1348_td=729
performance_1349_td=6812
performance_1350_td=Imola retrieve
performance_1351_td=ms
performance_1352_td=198
performance_1353_td=194
performance_1354_td=4036
performance_1355_td=Barcelona write
performance_1356_td=ms
performance_1357_td=413
performance_1358_td=832
performance_1359_td=3191
performance_1360_td=Barcelona read
performance_1361_td=ms
performance_1362_td=119
performance_1363_td=160
performance_1364_td=1177
performance_1365_td=Barcelona query
performance_1366_td=ms
performance_1367_td=20
performance_1368_td=5169
performance_1369_td=101
performance_1370_td=Barcelona delete
performance_1371_td=ms
performance_1372_td=388
performance_1373_td=319
performance_1374_td=3287
performance_1375_td=Total
performance_1376_td=ms
performance_1377_td=26724
performance_1378_td=53962
performance_1379_td=87112
performance_1380_h2=Application Profiling
performance_1381_h3=Analyze First
performance_1382_p=Before trying to optimize the performance, it is important to know where the time is actually spent. The same is true for memory problems. Premature or 'blind' optimization should be avoided, as it is not an efficient way to solve the problem. There are various ways to analyze the application. In some situations it is possible to compare two implementations and use System.currentTimeMillis() to find out which one is faster. But this does not work for complex applications with many modules, and for memory problems. A very good tool to measure both the memory and the CPU is the <a href\="http\://www.yourkit.com">YourKit Java Profiler</a> . This tool is also used to optimize the performance and memory footprint of this database engine.
performance_1383_h2=Database Performance Tuning
performance_1384_h3=Virus Scanners
performance_1385_p=Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine does never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow excluding file endings. Make sure files ending with .db are not scanned.
performance_1386_h3=Using the Trace Options
performance_1387_p=If the main performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see <a href\="features.html\#trace_options">Using the Trace Options</a> .
performance_1388_h3=Index Usage
performance_1389_p=This database uses indexes to improve the performance of SELECT, UPDATE and DELETE statements. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are not used to order result sets\:The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement.
performance_1390_h3=Optimizer
performance_1391_p=This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated.
performance_1392_h3=Expression Optimization
performance_1393_p=After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all.
performance_1394_h3=COUNT(*) Optimization
performance_1395_p=If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table.
performance_1397_p=When executing a query, at most one index per joined table can be used. If the same table is joined multiple times, for each join only one index is used. Example\:for the query SELECT * FROM TEST T1, TEST T2 WHERE T1.NAME\='A'AND T2.ID\=T1.ID, two index can be used, in this case the index on NAME for T1 and the index on ID for T2.
performance_1398_p=If a table has multiple indexes, sometimes more than one index could be used. Example\:if there is a table TEST(ID, NAME, FIRSTNAME) and an index on each column, then two indexes could be used for the query SELECT * FROM TEST WHERE NAME\='A'AND FIRSTNAME\='B', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of values in a column. A selectivity of 100 means each value appears only once, and a selectivity of 1 means the same value appears in many or most rows. For the query above, the index on NAME should be used if the table contains more distinct names than first names.
performance_1399_p=The SQL statement ANALYZE can be used to automatically estimate the selectivity of the columns in the tables. This command should be run from time to time to improve the query plans generated by the optimizer.
performance_1222_td=594255
performance_1223_td=Total Time
performance_1224_td=ms
performance_1225_td=55671
performance_1226_td=98063
performance_1227_td=151001
performance_1228_td=81811
performance_1229_td=57142
performance_1230_td=Statement per Second
performance_1231_td=\#
performance_1232_td=10674
performance_1233_td=6059
performance_1234_td=3935
performance_1235_td=7263
performance_1236_td=10399
performance_1237_h3=Benchmark Results and Comments
performance_1238_h4=H2
performance_1239_p=Version 1.0 (2007-09-15) was used for the test. For simpler operations, the performance of H2 is about the same as for HSQLDB. For more complex queries, the query optimizer is very important. However H2 is not very fast in every case, certain kind of queries may still be slow. One situation where is H2 is slow is large result sets, because they are buffered to disk if more than a certain number of records are returned. The advantage of buffering is, there is no limit on the result set size. The open/close time is almost fixed, because of the file locking protocol\:The engine waits 20 ms after opening a database to ensure the database files are not opened by another process.
performance_1240_h4=HSQLDB
performance_1241_p=Version 1.8.0.8 was used for the test. Cached tables are used in this test (hsqldb.default_table_type\=cached), and the write delay is 1 second (SET WRITE_DELAY 1). HSQLDB is fast when using simple operations. HSQLDB is very slow in the last test (BenchC\:Transactions), probably because is has a bad query optimizer. One query where HSQLDB is slow is a two-table join\:
performance_1242_p=The PolePosition benchmark also shows that the query optimizer does not do a very good job for some queries. A disadvantage in HSQLDB is the slow startup / shutdown time (currently not listed) when using bigger databases. The reason is, a backup of the database is created whenever the database is opened or closed.
performance_1243_h4=Derby
performance_1244_p=Version 10.3.1.4 was used for the test. Derby is clearly the slowest embedded database in this test. This seems to be a structural problem, because all operations are really slow. It will not be easy for the developers of Derby to improve the performance to a reasonable level. A few problems have been identified\:Leaving autocommit on is a problem for Derby. If it is switched off during the whole test, the results are about 20% better for Derby.
performance_1245_h4=PostgreSQL
performance_1246_p=Version 8.1.4 was used for the test. The following options where changed in postgresql.conf\:fsync \=off, commit_delay \=1000. PostgreSQL is run in server mode. It looks like the base performance is slower than MySQL, the reason could be the network layer. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
performance_1247_h4=MySQL
performance_1248_p=Version 5.0.22 was used for the test. MySQL was run with the InnoDB backend. The setting innodb_flush_log_at_trx_commit (found in the my.ini file) was set to 0. Otherwise (and by default), MySQL is really slow (around 140 statements per second in this test) because it tries to flush the data to disk for each commit. For small transactions (when autocommit is on) this is really slow. But many use cases use small or relatively small transactions. Too bad this setting is not listed in the configuration wizard, and it always overwritten when using the wizard. You need to change this setting manually in the file my.ini, and then restart the service. The memory usage number is incorrect, because only the memory usage of the JDBC driver is measured.
performance_1249_h4=Firebird
performance_1250_p=Firebird 1.5 (default installation) was tested, but the results are not published currently. It is possible to run the performance test with the Firebird database, and any information on how to configure Firebird for higher performance are welcome.
performance_1251_h4=Why Oracle / MS SQL Server / DB2 are Not Listed
performance_1252_p=The license of these databases does not allow to publish benchmark results. This doesn't mean that they are fast. They are in fact quite slow, and need a lot of memory. But you will need to test this yourself. SQLite was not tested because the JDBC driver doesn't support transactions.
performance_1253_h3=About this Benchmark
performance_1254_h4=Number of Connections
performance_1255_p=This is mostly a single-connection benchmark. BenchB uses multiple connections, the other tests one connection.
performance_1256_h4=Real-World Tests
performance_1257_p=Good benchmarks emulate real-world use cases. This benchmark includes 3 test cases\:A simple test case with one table and many small updates / deletes. BenchA is similar to the TPC-A test, but single connection / single threaded (see also\:www.tpc.org). BenchB is similar to the TPC-B test, using multiple connections (one thread per connection). BenchC is similar to the TPC-C test, but single connection / single threaded.
performance_1258_h4=Comparing Embedded with Server Databases
performance_1259_p=This is mainly a benchmark for embedded databases (where the application runs in the same virtual machine than the database engine). However MySQL and PostgreSQL are not Java databases and cannot be embedded into a Java application. For the Java databases, both embedded and server modes are tested.
performance_1260_h4=Test Platform
performance_1261_p=This test is run on Windows XP with the virus scanner switched off. The VM used is Sun JDK 1.5.
performance_1262_h4=Multiple Runs
performance_1263_p=When a Java benchmark is run first, the code is not fully compiled and therefore runs slower than when running multiple times. A benchmark should always run the same test multiple times and ignore the first run(s). This benchmark runs three times, the last run counts.
performance_1264_h4=Memory Usage
performance_1265_p=It is not enough to measure the time taken, the memory usage is important as well. Performance can be improved in databases by using a bigger in-memory cache, but there is only a limited amount of memory available on the system. HSQLDB tables are kept fully in memory by default, this benchmark uses 'disk based' tables for all databases. Unfortunately, it is not so easy to calculate the memory usage of PostgreSQL and MySQL, because they run in a different process than the test. This benchmark currently does not print memory usage of those databases.
performance_1266_h4=Delayed Operations
performance_1267_p=Some databases delay some operations (for example flushing the buffers) until after the benchmark is run. This benchmark waits between each database tested, and each database runs in a different process (sequentially).
performance_1269_p=Durability means transaction committed to the database will not be lost. Some databases (for example MySQL) try to enforce this by default by calling fsync() to flush the buffers, but most hard drives don't actually flush all data. Calling fsync() slows down transaction commit a lot, but doesn't always make data durable. When comparing the results, it is important to think about the effect. Many database suggest to 'batch' operations when possible. This benchmark switches off autocommit when loading the data, and calls commit after each 1000 inserts. However many applications need 'short' transactions at runtime (a commit after each update). This benchmark commits after each update / delete in the simple benchmark, and after each business transaction in the other benchmarks. For databases that support delayed commits, a delay of one second is used.
performance_1270_h4=Using Prepared Statements
performance_1271_p=Wherever possible, the test cases use prepared statements.
performance_1272_h4=Currently Not Tested\:Startup Time
performance_1273_p=The startup time of a database engine is important as well for embedded use. This time is not measured currently. Also, not tested is the time used to create a database and open an existing database. Here, one (wrapper) connection is opened at the start, and for each step a new connection is opened and then closed. That means the Open/Close time listed is for opening a connection if the database is already in use.
performance_1274_h2=PolePosition Benchmark
performance_1275_p=The PolePosition is an open source benchmark. The algorithms are all quite simple. It was developed / sponsored by db4o.
performance_1276_th=Test Case
performance_1277_th=Unit
performance_1278_th=H2
performance_1279_th=HSQLDB
performance_1280_th=MySQL
performance_1281_td=Melbourne write
performance_1282_td=ms
performance_1283_td=369
performance_1284_td=249
performance_1285_td=2022
performance_1286_td=Melbourne read
performance_1287_td=ms
performance_1288_td=47
performance_1289_td=49
performance_1290_td=93
performance_1291_td=Melbourne read_hot
performance_1292_td=ms
performance_1293_td=24
performance_1294_td=43
performance_1295_td=95
performance_1296_td=Melbourne delete
performance_1297_td=ms
performance_1298_td=147
performance_1299_td=133
performance_1300_td=176
performance_1301_td=Sepang write
performance_1302_td=ms
performance_1303_td=965
performance_1304_td=1201
performance_1305_td=3213
performance_1306_td=Sepang read
performance_1307_td=ms
performance_1308_td=765
performance_1309_td=948
performance_1310_td=3455
performance_1311_td=Sepang read_hot
performance_1312_td=ms
performance_1313_td=789
performance_1314_td=859
performance_1315_td=3563
performance_1316_td=Sepang delete
performance_1317_td=ms
performance_1318_td=1384
performance_1319_td=1596
performance_1320_td=6214
performance_1321_td=Bahrain write
performance_1322_td=ms
performance_1323_td=1186
performance_1324_td=1387
performance_1325_td=6904
performance_1326_td=Bahrain query_indexed_string
performance_1327_td=ms
performance_1328_td=336
performance_1329_td=170
performance_1330_td=693
performance_1331_td=Bahrain query_string
performance_1332_td=ms
performance_1333_td=18064
performance_1334_td=39703
performance_1335_td=41243
performance_1336_td=Bahrain query_indexed_int
performance_1337_td=ms
performance_1338_td=104
performance_1339_td=134
performance_1340_td=678
performance_1341_td=Bahrain update
performance_1342_td=ms
performance_1343_td=191
performance_1344_td=87
performance_1345_td=159
performance_1346_td=Bahrain delete
performance_1347_td=ms
performance_1348_td=1215
performance_1349_td=729
performance_1350_td=6812
performance_1351_td=Imola retrieve
performance_1352_td=ms
performance_1353_td=198
performance_1354_td=194
performance_1355_td=4036
performance_1356_td=Barcelona write
performance_1357_td=ms
performance_1358_td=413
performance_1359_td=832
performance_1360_td=3191
performance_1361_td=Barcelona read
performance_1362_td=ms
performance_1363_td=119
performance_1364_td=160
performance_1365_td=1177
performance_1366_td=Barcelona query
performance_1367_td=ms
performance_1368_td=20
performance_1369_td=5169
performance_1370_td=101
performance_1371_td=Barcelona delete
performance_1372_td=ms
performance_1373_td=388
performance_1374_td=319
performance_1375_td=3287
performance_1376_td=Total
performance_1377_td=ms
performance_1378_td=26724
performance_1379_td=53962
performance_1380_td=87112
performance_1381_h2=Application Profiling
performance_1382_h3=Analyze First
performance_1383_p=Before trying to optimize the performance, it is important to know where the time is actually spent. The same is true for memory problems. Premature or 'blind' optimization should be avoided, as it is not an efficient way to solve the problem. There are various ways to analyze the application. In some situations it is possible to compare two implementations and use System.currentTimeMillis() to find out which one is faster. But this does not work for complex applications with many modules, and for memory problems. A very good tool to measure both the memory and the CPU is the <a href\="http\://www.yourkit.com">YourKit Java Profiler</a> . This tool is also used to optimize the performance and memory footprint of this database engine.
performance_1384_h2=Database Performance Tuning
performance_1385_h3=Virus Scanners
performance_1386_p=Some virus scanners scan files every time they are accessed. It is very important for performance that database files are not scanned for viruses. The database engine does never interprets the data stored in the files as programs, that means even if somebody would store a virus in a database file, this would be harmless (when the virus does not run, it cannot spread). Some virus scanners allow excluding file endings. Make sure files ending with .db are not scanned.
performance_1387_h3=Using the Trace Options
performance_1388_p=If the main performance hot spots are in the database engine, in many cases the performance can be optimized by creating additional indexes, or changing the schema. Sometimes the application does not directly generate the SQL statements, for example if an O/R mapping tool is used. To view the SQL statements and JDBC API calls, you can use the trace options. For more information, see <a href\="features.html\#trace_options">Using the Trace Options</a> .
performance_1389_h3=Index Usage
performance_1390_p=This database uses indexes to improve the performance of SELECT, UPDATE and DELETE statements. If a column is used in the WHERE clause of a query, and if an index exists on this column, then the index can be used. Multi-column indexes are used if all or the first columns of the index are used. Both equality lookup and range scans are supported. Indexes are not used to order result sets\:The results are sorted in memory if required. Indexes are created automatically for primary key and unique constraints. Indexes are also created for foreign key constraints, if required. For other columns, indexes need to be created manually using the CREATE INDEX statement.
performance_1391_h3=Optimizer
performance_1392_p=This database uses a cost based optimizer. For simple and queries and queries with medium complexity (less than 7 tables in the join), the expected cost (running time) of all possible plans is calculated, and the plan with the lowest cost is used. For more complex queries, the algorithm first tries all possible combinations for the first few tables, and the remaining tables added using a greedy algorithm (this works well for most joins). Afterwards a genetic algorithm is used to test at most 2000 distinct plans. Only left-deep plans are evaluated.
performance_1393_h3=Expression Optimization
performance_1394_p=After the statement is parsed, all expressions are simplified automatically if possible. Operations are evaluated only once if all parameters are constant. Functions are also optimized, but only if the function is constant (always returns the same result for the same parameter values). If the WHERE clause is always false, then the table is not accessed at all.
performance_1395_h3=COUNT(*) Optimization
performance_1396_p=If the query only counts all rows of a table, then the data is not accessed. However, this is only possible if no WHERE clause is used, that means it only works for queries of the form SELECT COUNT(*) FROM table.
performance_1398_p=When executing a query, at most one index per joined table can be used. If the same table is joined multiple times, for each join only one index is used. Example\:for the query SELECT * FROM TEST T1, TEST T2 WHERE T1.NAME\='A'AND T2.ID\=T1.ID, two index can be used, in this case the index on NAME for T1 and the index on ID for T2.
performance_1399_p=If a table has multiple indexes, sometimes more than one index could be used. Example\:if there is a table TEST(ID, NAME, FIRSTNAME) and an index on each column, then two indexes could be used for the query SELECT * FROM TEST WHERE NAME\='A'AND FIRSTNAME\='B', the index on NAME or the index on FIRSTNAME. It is not possible to use both indexes at the same time. Which index is used depends on the selectivity of the column. The selectivity describes the 'uniqueness' of values in a column. A selectivity of 100 means each value appears only once, and a selectivity of 1 means the same value appears in many or most rows. For the query above, the index on NAME should be used if the table contains more distinct names than first names.
performance_1400_p=The SQL statement ANALYZE can be used to automatically estimate the selectivity of the columns in the tables. This command should be run from time to time to improve the query plans generated by the optimizer.
quickstartText_1000_h1=Quickstart
quickstartText_1001_a=Embedding H2 in an Application
quickstartText_1002_a=The H2 Console Application
...
...
@@ -1518,136 +1519,141 @@ tutorial_1008_a=Upgrade, Backup, and Restore
tutorial_1009_a=Using OpenOffice Base
tutorial_1010_a=Java Web Start / JNLP
tutorial_1011_a=Fulltext Search
tutorial_1012_h2=Starting and Using the H2 Console
tutorial_1013_p=This application lets you access a SQL database using a browser interface. This can be a H2 database, or another database that supports the JDBC API.
tutorial_1014_p=This is a client / server application, so both a server and a client (a browser) are required to run it.
tutorial_1015_p=Depending on your platform and environment, there are multiple ways to start the application\:
tutorial_1016_th=OS
tutorial_1017_th=Start
tutorial_1018_td=Windows
tutorial_1019_td=Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]
tutorial_1020_td=When using the Sun JDK 1.4 or 1.5, a window with the title 'H2 Console ' should appear. When using the Sun JDK 1.6, an icon will be added to the system tray\:
tutorial_1021_td=If you don't get the window and the system tray icon, then maybe Java is not installed correctly (in this case, try another way to start the application). A browser window should open and point to the Login page http\://localhost\:8082).
tutorial_1022_td=Windows
tutorial_1023_td=Open a file browser, navigate to h2/bin, and double click on h2.bat.
tutorial_1024_td=A console window appears. If there is a problem, you will see an error message in this window. A browser window will open and point to the Login page (URL\:http\://localhost\:8082).
tutorial_1025_td=Any
tutorial_1026_td=Open a console window, navigate to the directory 'h2/bin' and type\:
tutorial_1027_h3=Firewall
tutorial_1028_p=If you start the server, you may get a security warning from the firewall (if you have installed one). If you don't want other computers in the network to access the application on your machine, you can let the firewall block those connections. The connection from the local machine will still work. Only if you want other computers to access the database on this computer, you need allow remote connections in the firewall.
tutorial_1029_p=A small firewall is already built into the server\:other computers may not connect to the server by default. To change this, go to 'Preferences' and select 'Allow connections from other computers'.
tutorial_1030_h3=Native Version
tutorial_1031_p=The native version does not require Java, because it is compiled using GCJ. However H2 does currently not run stable with GCJ on Windows It is possible to compile the software to different platforms.
tutorial_1032_h3=Testing Java
tutorial_1033_p=To check the Java version you have installed, open a command prompt and type\:
tutorial_1034_p=If you get an error message, you may need to add the Java binary directory to the path environment variable.
tutorial_1035_h3=Error Message 'Port is in use'
tutorial_1036_p=You can only start one instance of the H2 Console, otherwise you will get the following error message\:<code>Port is in use, maybe another ... server already running on...</code> . It is possible to start multiple console applications on the same computer (using different ports), but this is usually not required as the console supports multiple concurrent connections.
tutorial_1037_h3=Using another Port
tutorial_1038_p=If the port is in use by another application, you may want to start the H2 Console on a different port. This can be done by changing the port in the file .h2.server.properties. This file is stored in the user directory (for Windows, this is usually in "Documents and Settings/<username>"). The relevant entry is webPort.
tutorial_1039_h3=Starting Successfully
tutorial_1040_p=If starting the server from a console window was successful, a new window will open and display the following text\:
tutorial_1041_p=Don't click inside this window; otherwise you might block the application (if you have the Fast-Edit mode enabled).
tutorial_1042_h3=Connecting to the Server using a Browser
tutorial_1043_p=If the server started successfully, you can connect to it using a web browser. The browser needs to support JavaScript, frames and cascading stylesheets (css). If you started the server on the same computer as the browser, go to http\://localhost\:8082 in the browser. If you want to connect to the application from another computer, you need to provide the IP address of the server, for example\:http\://192.168.0.2\:8082. If you enabled SSL on the server side, the URL needs to start with HTTPS.
tutorial_1044_h3=Multiple Concurrent Sessions
tutorial_1045_p=Multiple concurrent browser sessions are supported. As that the database objects reside on the server, the amount of concurrent work is limited by the memory available to the server application.
tutorial_1046_h3=Application Properties
tutorial_1047_p=Starting the server will create a configuration file in you local home directory called <code>.h2.server.properties</code> . For Windows installations, this file will be in the directory <code>C\:\\Documents and Settings\\[username]</code> . This file contains the settings of the application.
tutorial_1048_h3=Login
tutorial_1049_p=At the login page, you need to provide connection information to connect to a database. Set the JDBC driver class of your database, the JDBC URL, user name and password. If you are done, click [Connect].
tutorial_1050_p=You can save and reuse previously saved settings. The settings are stored in the Application Properties file.
tutorial_1051_h3=Error Messages
tutorial_1052_p=Error messages in are shown in red. You can show/hide the stack trace of the exception by clicking on the message.
tutorial_1053_h3=Adding Database Drivers
tutorial_1054_p=Additional database drivers can be registered by adding the Jar file location of the driver to the environment variables H2DRIVERS or CLASSPATH. Example (Windows)\:To add the database driver library C\:\\Programs\\hsqldb\\lib\\hsqldb.jar, set the environment variable H2DRIVERS to C\:\\Programs\\hsqldb\\lib\\hsqldb.jar.
tutorial_1055_p=Multiple drivers can be set; each entry needs to be separated with a ';' (Windows) or '\:' (other operating systems). Spaces in the path names are supported. The settings must not be quoted.
tutorial_1056_p=Only the Java version supports additional drivers (this feature is not supported by the Native version).
tutorial_1057_h3=Using the Application
tutorial_1058_p=The application has three main panels, the toolbar on top, the tree on the left and the query / result panel on the right. The database objects (for example, tables) are listed on the left panel. Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command.
tutorial_1059_h3=Inserting Table Names or Column Names
tutorial_1060_p=The table name and column names can be inserted in the script by clicking them in the tree. If you click on a table while the query is empty, a 'SELECT * FROM ...' is added as well. While typing a query, the table that was used is automatically expanded in the tree. For, example if you type 'SELECT * FROM TEST T WHERE T.' then the table TEST is automatically expanded in the tree.
tutorial_1061_h3=Disconnecting and Stopping the Application
tutorial_1062_p=On the browser, click 'Disconnect' on the toolbar panel. You will be logged out of the database. However, the server is still running and ready to accept new sessions.
tutorial_1063_p=To stop the server, right click on the system tray icon and select [Exit]. If you don't have the icon (because you started it in another way), press [Ctrl]+[C] on the console where the server was started (Windows), or close the console window.
tutorial_1064_h2=Connecting to a Database using JDBC
tutorial_1065_p=To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code\:
tutorial_1066_p=This code first loads the driver ( <code>Class.forName()</code> ) and then opens a connection (using <code>DriverManager.getConnection()</code> ). The driver name is <code>"org.h2.Driver"</code> in every case. The database URL always needs to start with <code>jdbc\:h2\:</code> to be recognized by this database. The second parameter in the <code>getConnection()</code> call is the user name ('sa' for System Administrator in this example). The third parameter is the password. Please note that in this database, user names are not case sensitive, but passwords are case sensitive.
tutorial_1067_h2=Creating New Databases
tutorial_1068_p=By default, if the database specified in the URL does not yet exist, a new (empty) database is created automatically. The user that created the database automatically becomes the administrator of this database.
tutorial_1069_h2=Using the Server
tutorial_1070_p=H2 currently supports three servers\:a Web Server, a TCP Server and an ODBC Server. The servers can be started in different ways.
tutorial_1071_h3=Starting the Server from Command Line
tutorial_1072_p=To start the Server from the command line with the default settings, run
tutorial_1073_p=This will start the Server with the default options. To get the list of options and default values, run
tutorial_1074_p=There are options available to use a different ports, and start or not start parts of the Server and so on. For details, see the API documentation of the Server tool.
tutorial_1075_h3=Connecting to the TCP Server
tutorial_1076_p=To remotly connect to a database using the TCP server, use the following driver and database URL\:
tutorial_1079_p=For details about the database URL, see also in Features.
tutorial_1080_h3=Starting the Server within an Application
tutorial_1081_p=It is also possible to start and stop a Server from within an application. Sample code\:
tutorial_1082_h3=Stopping a TCP Server from Another Process
tutorial_1083_p=The TCP Server can be stopped from another process. To stop the server from the command line, run\:
tutorial_1084_p=To stop the server from a user application, use the following code\:
tutorial_1085_p=This function will call System.exit on the server. This function should be called after all connection to the databases are closed to avoid recovery when the databases are opened the next time. To stop remote server, remote connections must be enabled on the server.
tutorial_1086_h3=Limitations of the Server
tutorial_1087_p=There currently are a few limitations when using the server or cluster mode\:
tutorial_1088_li=Statement.cancel() is only supported in embedded mode. A connection can only execute one operation at a time in server or cluster mode, and is blocked until this operation is finished.
tutorial_1089_h2=Using Hibernate
tutorial_1090_p=This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, or the native H2 Dialect that is available in the file src/tools/org/h2/tools/hibernate/H2Dialect.txt. The H2 dialect is included in newer version of Hibernate. For versions where the dialect is missing, you need to copy the file into the folder src\\org\\hibernate\\dialect (Hibernate 3.1), rename it to H2Dialect.java and re-compile hibernate.
tutorial_1091_h2=Using Databases in Web Applications
tutorial_1092_p=There are multiple ways to access a database from within web applications. Here are some examples if you use Tomcat or JBoss.
tutorial_1093_h3=Embedded Mode
tutorial_1094_p=The (currently) most simple solution is to use the database in the embedded mode, that means open a connection in your application when it starts (a good solution is using a Servlet Listener, see below), or when a session starts. A database can be accessed from multiple sessions and applications at the same time, as long as they run in the same process. Most Servlet Containers (for example Tomcat) are just using one process, so this is not a problem (unless you run Tomcat in clustered mode). Tomcat uses multiple threads and multiple classloaders. If multiple applications access the same database at the same time, you need to put the database jar in the shared/lib or server/lib directory. It is a good idea to open the database when the web application starts, and close it when the web applications stops. If using multiple applications, only one (any) of them needs to do that. In the application, an idea is to use one connection per Session, or even one connection per request (action). Those connections should be closed after use if possible (but it's not that bad if they don't get closed).
tutorial_1095_h3=Server Mode
tutorial_1096_p=The server mode is similar, but it allows you to run the server in another process.
tutorial_1097_h3=Using a Servlet Listener to Start and Stop a Database
tutorial_1098_p=Add the h2.jar file your web application, and add the following snippet to your web.xml file (after context-param and before filter)\:
tutorial_1099_p=For details on how to access the database, see the code DbStarter.java
tutorial_1100_h2=CSV (Comma Separated Values) Support
tutorial_1101_p=The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE, and the CSV library can be used outside the database as a standalone tool.
tutorial_1102_h3=Writing a CSV File from Within a Database
tutorial_1103_p=The built-in function CSVWRITE can be used to create a CSV file from a query. Example\:
tutorial_1104_h3=Reading a CSV File from Within a Database
tutorial_1105_p=A CSV file can be read using the function CSVREAD. Example\:
tutorial_1106_h3=Writing a CSV File from a Java Application
tutorial_1107_p=The CSV tool can be used in a Java application even when not using a database at all. Example\:
tutorial_1108_h3=Reading a CSV File from a Java Application
tutorial_1109_p=It is possible to read a CSV file without opening a database. Example\:
tutorial_1110_h2=Upgrade, Backup, and Restore
tutorial_1111_h3=Database Upgrade
tutorial_1112_p=The recommended way to upgrade from one version of the database engine to the next version is to create a backup of the database (in the form of a SQL script) using the old engine, and then execute the SQL script using the new engine.
tutorial_1113_h3=Backup using the Script Tool
tutorial_1114_p=There are different ways to backup a database. For example, it is possible to copy the database files. However, this is not recommended while the database is in use. Also, the database files are not human readable and quite large. The recommended way to backup a database is to create a compressed SQL script file. This can be done using the Script tool\:
tutorial_1115_p=It is also possible to use the SQL command SCRIPT to create the backup of the database. For more information about the options, see the SQL command SCRIPT. The backup can be done remotely, however the file will be created on the server side. The built in FTP server could be used to retrieve the file from the server.
tutorial_1116_h3=Restore from a Script
tutorial_1117_p=To restore a database from a SQL script file, you can use the RunScript tool\:
tutorial_1118_p=For more information about the options, see the SQL command RUNSCRIPT. The restore can be done remotely, however the file needs to be on the server side. The built in FTP server could be used to copy the file to the server. It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. SQL script files may contain references to other script files, in the form of RUNSCRIPT commands. However, when using the server mode, the references script files need to be available on the server side.
tutorial_1119_h3=Online Backup
tutorial_1120_p=The BACKUP SQL statement and the Backup tool both create a zip file with all database files. However, the contents of this file are not human readable. Other than the SCRIPT statement, the BACKUP statement does not lock the database objects, and therefore does not block other users. The resulting backup is transactionally consistent\:
tutorial_1121_p=The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; the database must not be in use while running this program.
tutorial_1122_h2=Using OpenOffice Base
tutorial_1123_p=OpenOffice.org Base supports database access over the JDBC API. To connect to a H2 database using OpenOffice Base, you first need to add the JDBC driver to OpenOffice. The steps to connect to a H2 database are\:
tutorial_1124_li=Stop OpenOffice, including the autostart
tutorial_1125_li=Copy h2.jar into the directory <OpenOffice>\\program\\classes
tutorial_1126_li=Start OpenOffice Base
tutorial_1127_li=Connect to an existing database, select JDBC, [Next]
tutorial_1130_p=Now you can access the database stored in the directory C\:/temp.
tutorial_1131_h2=Java Web Start / JNLP
tutorial_1132_p=When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following exception will occur\:java.security.AccessControlException\:access denied (java.io.FilePermission ... read). Example permission tags\:
tutorial_1133_h2=Fulltext Search
tutorial_1134_p=H2 supports Lucene full text search and native full text search implementation.
tutorial_1135_h3=Using the Native Full Text Search
tutorial_1136_p=To initialize, call\:
tutorial_1137_p=You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using\:
tutorial_1138_p=PUBLIC is the schema, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in read time. To search the index, use the following query\:
tutorial_1139_p=You can also call the index from within a Java application\:
tutorial_1140_h3=Using the Lucene Fulltext Search
tutorial_1141_p=To use the Lucene full text search, you need the Lucene library in the classpath. How his is done depends on the application; if you use the H2 Console, you can add the Lucene jar file to the the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene full text search in a database, call\:
tutorial_1142_p=You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using\:
tutorial_1143_p=PUBLIC is the schema, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in read time. To search the index, use the following query\:
tutorial_1144_p=You can also call the index from within a Java application\:
tutorial_1012_a=User Defined Variables
tutorial_1013_h2=Starting and Using the H2 Console
tutorial_1014_p=This application lets you access a SQL database using a browser interface. This can be a H2 database, or another database that supports the JDBC API.
tutorial_1015_p=This is a client / server application, so both a server and a client (a browser) are required to run it.
tutorial_1016_p=Depending on your platform and environment, there are multiple ways to start the application\:
tutorial_1017_th=OS
tutorial_1018_th=Start
tutorial_1019_td=Windows
tutorial_1020_td=Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]
tutorial_1021_td=When using the Sun JDK 1.4 or 1.5, a window with the title 'H2 Console ' should appear. When using the Sun JDK 1.6, an icon will be added to the system tray\:
tutorial_1022_td=If you don't get the window and the system tray icon, then maybe Java is not installed correctly (in this case, try another way to start the application). A browser window should open and point to the Login page http\://localhost\:8082).
tutorial_1023_td=Windows
tutorial_1024_td=Open a file browser, navigate to h2/bin, and double click on h2.bat.
tutorial_1025_td=A console window appears. If there is a problem, you will see an error message in this window. A browser window will open and point to the Login page (URL\:http\://localhost\:8082).
tutorial_1026_td=Any
tutorial_1027_td=Open a console window, navigate to the directory 'h2/bin' and type\:
tutorial_1028_h3=Firewall
tutorial_1029_p=If you start the server, you may get a security warning from the firewall (if you have installed one). If you don't want other computers in the network to access the application on your machine, you can let the firewall block those connections. The connection from the local machine will still work. Only if you want other computers to access the database on this computer, you need allow remote connections in the firewall.
tutorial_1030_p=A small firewall is already built into the server\:other computers may not connect to the server by default. To change this, go to 'Preferences' and select 'Allow connections from other computers'.
tutorial_1031_h3=Native Version
tutorial_1032_p=The native version does not require Java, because it is compiled using GCJ. However H2 does currently not run stable with GCJ on Windows It is possible to compile the software to different platforms.
tutorial_1033_h3=Testing Java
tutorial_1034_p=To check the Java version you have installed, open a command prompt and type\:
tutorial_1035_p=If you get an error message, you may need to add the Java binary directory to the path environment variable.
tutorial_1036_h3=Error Message 'Port is in use'
tutorial_1037_p=You can only start one instance of the H2 Console, otherwise you will get the following error message\:<code>Port is in use, maybe another ... server already running on...</code> . It is possible to start multiple console applications on the same computer (using different ports), but this is usually not required as the console supports multiple concurrent connections.
tutorial_1038_h3=Using another Port
tutorial_1039_p=If the port is in use by another application, you may want to start the H2 Console on a different port. This can be done by changing the port in the file .h2.server.properties. This file is stored in the user directory (for Windows, this is usually in "Documents and Settings/<username>"). The relevant entry is webPort.
tutorial_1040_h3=Starting Successfully
tutorial_1041_p=If starting the server from a console window was successful, a new window will open and display the following text\:
tutorial_1042_p=Don't click inside this window; otherwise you might block the application (if you have the Fast-Edit mode enabled).
tutorial_1043_h3=Connecting to the Server using a Browser
tutorial_1044_p=If the server started successfully, you can connect to it using a web browser. The browser needs to support JavaScript, frames and cascading stylesheets (css). If you started the server on the same computer as the browser, go to http\://localhost\:8082 in the browser. If you want to connect to the application from another computer, you need to provide the IP address of the server, for example\:http\://192.168.0.2\:8082. If you enabled SSL on the server side, the URL needs to start with HTTPS.
tutorial_1045_h3=Multiple Concurrent Sessions
tutorial_1046_p=Multiple concurrent browser sessions are supported. As that the database objects reside on the server, the amount of concurrent work is limited by the memory available to the server application.
tutorial_1047_h3=Application Properties
tutorial_1048_p=Starting the server will create a configuration file in you local home directory called <code>.h2.server.properties</code> . For Windows installations, this file will be in the directory <code>C\:\\Documents and Settings\\[username]</code> . This file contains the settings of the application.
tutorial_1049_h3=Login
tutorial_1050_p=At the login page, you need to provide connection information to connect to a database. Set the JDBC driver class of your database, the JDBC URL, user name and password. If you are done, click [Connect].
tutorial_1051_p=You can save and reuse previously saved settings. The settings are stored in the Application Properties file.
tutorial_1052_h3=Error Messages
tutorial_1053_p=Error messages in are shown in red. You can show/hide the stack trace of the exception by clicking on the message.
tutorial_1054_h3=Adding Database Drivers
tutorial_1055_p=Additional database drivers can be registered by adding the Jar file location of the driver to the environment variables H2DRIVERS or CLASSPATH. Example (Windows)\:To add the database driver library C\:\\Programs\\hsqldb\\lib\\hsqldb.jar, set the environment variable H2DRIVERS to C\:\\Programs\\hsqldb\\lib\\hsqldb.jar.
tutorial_1056_p=Multiple drivers can be set; each entry needs to be separated with a ';' (Windows) or '\:' (other operating systems). Spaces in the path names are supported. The settings must not be quoted.
tutorial_1057_p=Only the Java version supports additional drivers (this feature is not supported by the Native version).
tutorial_1058_h3=Using the Application
tutorial_1059_p=The application has three main panels, the toolbar on top, the tree on the left and the query / result panel on the right. The database objects (for example, tables) are listed on the left panel. Type in a SQL command on the query panel and click 'Run'. The result of the command appears just below the command.
tutorial_1060_h3=Inserting Table Names or Column Names
tutorial_1061_p=The table name and column names can be inserted in the script by clicking them in the tree. If you click on a table while the query is empty, a 'SELECT * FROM ...' is added as well. While typing a query, the table that was used is automatically expanded in the tree. For, example if you type 'SELECT * FROM TEST T WHERE T.' then the table TEST is automatically expanded in the tree.
tutorial_1062_h3=Disconnecting and Stopping the Application
tutorial_1063_p=On the browser, click 'Disconnect' on the toolbar panel. You will be logged out of the database. However, the server is still running and ready to accept new sessions.
tutorial_1064_p=To stop the server, right click on the system tray icon and select [Exit]. If you don't have the icon (because you started it in another way), press [Ctrl]+[C] on the console where the server was started (Windows), or close the console window.
tutorial_1065_h2=Connecting to a Database using JDBC
tutorial_1066_p=To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code\:
tutorial_1067_p=This code first loads the driver ( <code>Class.forName()</code> ) and then opens a connection (using <code>DriverManager.getConnection()</code> ). The driver name is <code>"org.h2.Driver"</code> in every case. The database URL always needs to start with <code>jdbc\:h2\:</code> to be recognized by this database. The second parameter in the <code>getConnection()</code> call is the user name ('sa' for System Administrator in this example). The third parameter is the password. Please note that in this database, user names are not case sensitive, but passwords are case sensitive.
tutorial_1068_h2=Creating New Databases
tutorial_1069_p=By default, if the database specified in the URL does not yet exist, a new (empty) database is created automatically. The user that created the database automatically becomes the administrator of this database.
tutorial_1070_h2=Using the Server
tutorial_1071_p=H2 currently supports three servers\:a Web Server, a TCP Server and an ODBC Server. The servers can be started in different ways.
tutorial_1072_h3=Starting the Server from Command Line
tutorial_1073_p=To start the Server from the command line with the default settings, run
tutorial_1074_p=This will start the Server with the default options. To get the list of options and default values, run
tutorial_1075_p=There are options available to use a different ports, and start or not start parts of the Server and so on. For details, see the API documentation of the Server tool.
tutorial_1076_h3=Connecting to the TCP Server
tutorial_1077_p=To remotly connect to a database using the TCP server, use the following driver and database URL\:
tutorial_1080_p=For details about the database URL, see also in Features.
tutorial_1081_h3=Starting the Server within an Application
tutorial_1082_p=It is also possible to start and stop a Server from within an application. Sample code\:
tutorial_1083_h3=Stopping a TCP Server from Another Process
tutorial_1084_p=The TCP Server can be stopped from another process. To stop the server from the command line, run\:
tutorial_1085_p=To stop the server from a user application, use the following code\:
tutorial_1086_p=This function will call System.exit on the server. This function should be called after all connection to the databases are closed to avoid recovery when the databases are opened the next time. To stop remote server, remote connections must be enabled on the server.
tutorial_1087_h3=Limitations of the Server
tutorial_1088_p=There currently are a few limitations when using the server or cluster mode\:
tutorial_1089_li=Statement.cancel() is only supported in embedded mode. A connection can only execute one operation at a time in server or cluster mode, and is blocked until this operation is finished.
tutorial_1090_h2=Using Hibernate
tutorial_1091_p=This database supports Hibernate version 3.1 and newer. You can use the HSQLDB Dialect, or the native H2 Dialect that is available in the file src/tools/org/h2/tools/hibernate/H2Dialect.txt. The H2 dialect is included in newer version of Hibernate. For versions where the dialect is missing, you need to copy the file into the folder src\\org\\hibernate\\dialect (Hibernate 3.1), rename it to H2Dialect.java and re-compile hibernate.
tutorial_1092_h2=Using Databases in Web Applications
tutorial_1093_p=There are multiple ways to access a database from within web applications. Here are some examples if you use Tomcat or JBoss.
tutorial_1094_h3=Embedded Mode
tutorial_1095_p=The (currently) most simple solution is to use the database in the embedded mode, that means open a connection in your application when it starts (a good solution is using a Servlet Listener, see below), or when a session starts. A database can be accessed from multiple sessions and applications at the same time, as long as they run in the same process. Most Servlet Containers (for example Tomcat) are just using one process, so this is not a problem (unless you run Tomcat in clustered mode). Tomcat uses multiple threads and multiple classloaders. If multiple applications access the same database at the same time, you need to put the database jar in the shared/lib or server/lib directory. It is a good idea to open the database when the web application starts, and close it when the web applications stops. If using multiple applications, only one (any) of them needs to do that. In the application, an idea is to use one connection per Session, or even one connection per request (action). Those connections should be closed after use if possible (but it's not that bad if they don't get closed).
tutorial_1096_h3=Server Mode
tutorial_1097_p=The server mode is similar, but it allows you to run the server in another process.
tutorial_1098_h3=Using a Servlet Listener to Start and Stop a Database
tutorial_1099_p=Add the h2.jar file your web application, and add the following snippet to your web.xml file (after context-param and before filter)\:
tutorial_1100_p=For details on how to access the database, see the code DbStarter.java
tutorial_1101_h2=CSV (Comma Separated Values) Support
tutorial_1102_p=The CSV file support can be used inside the database using the functions CSVREAD and CSVWRITE, and the CSV library can be used outside the database as a standalone tool.
tutorial_1103_h3=Writing a CSV File from Within a Database
tutorial_1104_p=The built-in function CSVWRITE can be used to create a CSV file from a query. Example\:
tutorial_1105_h3=Reading a CSV File from Within a Database
tutorial_1106_p=A CSV file can be read using the function CSVREAD. Example\:
tutorial_1107_h3=Writing a CSV File from a Java Application
tutorial_1108_p=The CSV tool can be used in a Java application even when not using a database at all. Example\:
tutorial_1109_h3=Reading a CSV File from a Java Application
tutorial_1110_p=It is possible to read a CSV file without opening a database. Example\:
tutorial_1111_h2=Upgrade, Backup, and Restore
tutorial_1112_h3=Database Upgrade
tutorial_1113_p=The recommended way to upgrade from one version of the database engine to the next version is to create a backup of the database (in the form of a SQL script) using the old engine, and then execute the SQL script using the new engine.
tutorial_1114_h3=Backup using the Script Tool
tutorial_1115_p=There are different ways to backup a database. For example, it is possible to copy the database files. However, this is not recommended while the database is in use. Also, the database files are not human readable and quite large. The recommended way to backup a database is to create a compressed SQL script file. This can be done using the Script tool\:
tutorial_1116_p=It is also possible to use the SQL command SCRIPT to create the backup of the database. For more information about the options, see the SQL command SCRIPT. The backup can be done remotely, however the file will be created on the server side. The built in FTP server could be used to retrieve the file from the server.
tutorial_1117_h3=Restore from a Script
tutorial_1118_p=To restore a database from a SQL script file, you can use the RunScript tool\:
tutorial_1119_p=For more information about the options, see the SQL command RUNSCRIPT. The restore can be done remotely, however the file needs to be on the server side. The built in FTP server could be used to copy the file to the server. It is also possible to use the SQL command RUNSCRIPT to execute a SQL script. SQL script files may contain references to other script files, in the form of RUNSCRIPT commands. However, when using the server mode, the references script files need to be available on the server side.
tutorial_1120_h3=Online Backup
tutorial_1121_p=The BACKUP SQL statement and the Backup tool both create a zip file with all database files. However, the contents of this file are not human readable. Other than the SCRIPT statement, the BACKUP statement does not lock the database objects, and therefore does not block other users. The resulting backup is transactionally consistent\:
tutorial_1122_p=The Backup tool (org.h2.tools.Backup) can not be used to create a online backup; the database must not be in use while running this program.
tutorial_1123_h2=Using OpenOffice Base
tutorial_1124_p=OpenOffice.org Base supports database access over the JDBC API. To connect to a H2 database using OpenOffice Base, you first need to add the JDBC driver to OpenOffice. The steps to connect to a H2 database are\:
tutorial_1125_li=Stop OpenOffice, including the autostart
tutorial_1126_li=Copy h2.jar into the directory <OpenOffice>\\program\\classes
tutorial_1127_li=Start OpenOffice Base
tutorial_1128_li=Connect to an existing database, select JDBC, [Next]
tutorial_1131_p=Now you can access the database stored in the directory C\:/temp.
tutorial_1132_h2=Java Web Start / JNLP
tutorial_1133_p=When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tags must be set in the .jnlp file, and the application .jar file must be signed. Otherwise, when trying to write to the file system, the following exception will occur\:java.security.AccessControlException\:access denied (java.io.FilePermission ... read). Example permission tags\:
tutorial_1134_h2=Fulltext Search
tutorial_1135_p=H2 supports Lucene full text search and native full text search implementation.
tutorial_1136_h3=Using the Native Full Text Search
tutorial_1137_p=To initialize, call\:
tutorial_1138_p=You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using\:
tutorial_1139_p=PUBLIC is the schema, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in read time. To search the index, use the following query\:
tutorial_1140_p=You can also call the index from within a Java application\:
tutorial_1141_h3=Using the Lucene Fulltext Search
tutorial_1142_p=To use the Lucene full text search, you need the Lucene library in the classpath. How his is done depends on the application; if you use the H2 Console, you can add the Lucene jar file to the the environment variables H2DRIVERS or CLASSPATH. To initialize the Lucene full text search in a database, call\:
tutorial_1143_p=You need to initialize it in each database where you want to use it. Afterwards, you can create a full text index for a table using\:
tutorial_1144_p=PUBLIC is the schema, TEST is the table name. The list of column names (column separated) is optional, in this case all columns are indexed. The index is updated in read time. To search the index, use the following query\:
tutorial_1145_p=You can also call the index from within a Java application\:
tutorial_1146_h2=User Defined Variables
tutorial_1147_p=This database supports user defined variables. Variables start with @ and can be used whereever expressions or parameters are used. Variables not persisted and session scoped, that means only visible for the session where they are defined. A value is usually assigned using the SET command\:
tutorial_1148_p=It is also possible to change a value using the SET() method. This is useful in queries\:
tutorial_1149_p=Variables that are not set evaluate to NULL. The data type of a user defined variable is the data type of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them. There are no restrictions on the assigned values, large objects (LOBs) are supported as well.