Эта публикация является односторонним сравнением популярных реляционных баз данных. А именно: по времени выполнения SQL-запросов в различных БД при прочих равных условиях (тип запроса и размер таблицы).
Заметка: если вас интересует только результат тестирования — прошу к разделу Результаты.
Введение
Возник вопрос о выборе базы данных для веб-проекта. В рассматриваемом списке присутствовали: H2, MySQL (раздельно реализации InnoDB и MyISAM), MariaDB, PostgreSQL, Oracle g11 r2. Пришла мысль измерить скорость выполнения Java-кода по выполнению запроса к различным базам данных.
Для измерения скорости выбор пал на библиотеку JMH. Подключается просто, через maven-dependency в pom.xml:
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
<properties>
<jmh.version>1.19</jmh.version>
</properties>
Написание Java-метода для тестирования весьма лаконично, аннотации говорят сами за себя:
@State(Scope.Thread)
public class H2 {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public ResultSet testMethod() throws SQLException, ClassNotFoundException {
ResultSet resultSet = statement.executeQuery(someQuery);
return resultSet;
}
}
Для JMH важно чтобы метод имел возвращаемый тип данных.
Запуск тестового метода выполняется из public static void main:
public static void main(String[] args) throws RunnerException, ClassNotFoundException, SQLException {
Options opt = new OptionsBuilder()
.include(H2.class.getSimpleName())
.warmupIterations(10)
.measurementIterations(10)
.forks(1)
.build();
new Runner(opt).run();
}
Перед запуском необходимо собрать проект через командную строку:
mvn clean install
Результат сборку должен будет представлять что-то вроде этого:
В pom.xml необходимо добавить maven-dependency для БД:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
До того как производить выборку, необходимо создать таблицу с заданным количеством строк. Для подобного рода подготовительных операций в JMH существует аннотация Setup:
@Setup
public void prepare() throws ClassNotFoundException, SQLException {
Class.forName(driverName);
connection = DriverManager.getConnection(connectionName, root, password);
statement = connection.createStatement();
statement.execute("CREATE TABLE ...");
for (int i = 0; i < rowCount; i++) {
statement.execute("INSERT INTO ...");
}
}
Для разрыва соединения и удаления таблицы по завершении метода используется аннотация TearDown:
@TearDown
public void disconnect() throws SQLException {
statement.execute("DROP TABLE ...");
connection.close();
}
Результаты
Согласно скорости выполнения кода по запросу к БД в таблицах размером от 100 до 100 000 строк на моем компьютере, рассматриваемые БД расположены в следующем порядке (время запроса выражено в микросекундах):
1-2. Oracle | 1-2. PostgreSQL | 2. H2 | 3. MyISAM | 4-5. MariaDB | 4-5. InnoDB | |
---|---|---|---|---|---|---|
100 строк | 499, 774 | 435, 367 | 124, 041 | 387, 613 | 487, 720 | 545, 770 |
1000 строк | 559, 887 | 714, 510 | 708, 488 | 1 441, 750 | 2 634, 031 | 2 611, 083 |
10 000 строк | 8 842, 546 | 4 236, 861 | 9 433, 653 | 10 359, 910 | 26 056, 574 | 25 008, 635 |
100 000 строк | 18 965, 460 | 36 947, 172 | 2 357 105, 910 | 99 816, 738 | — * | — * |
* Не смог дождаться выполнения кода
Весь исходный код расположен здесь.
Буду благодарен любой конструктивной критике и советам, а также результатам тестирования на вашем железе.
Надеюсь статья оказалась вам полезной/интересной, раз вы дочитали до конца!
Автор: new player