SQLite: быстродействие транзакций

SQLite3 на хостингах обычно встречается в связке с PDO. Это одно из главных преимуществ SQLite, потому что в случае нехватки быстродействия можно легко перейти на MySQL, всего лишь изменив настройки подключения к базе данных.

В процессе изучения PDO, я не обращал особого внимания на транзакции, как оказалоь зря. Они позволяют отменить группу SQL запросов, если один из них будет неудачен. Это основная задача транзакций. Их еще одним полезным свойством является ускорение выполнения нескольких запросов.

Сравнение времени записи в бд с транзакциями и без них.


Конфигурация сервера: ОС - win, CPU - Athlon 2000, RAM - 1Gb.

Для тестов возьмем скрипт записи десяти тысяч строк в пустую базу данных SQLite3.

С транзакциями:

<?php
define ('START_TIME', microtime(TRUE));

$db = new PDO('sqlite:db.sqlite3');

$db->exec('CREATE TABLE `test` (
         id INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
         name VARCHAR(255)  NOT NULL,
         surname VARCHAR(255)  NOT NULL,
         age NUMERIC  NOT NULL
   )');

$db->beginTransaction();
	
for ($i = 1; $i <= 10000; $i++) {

	$db->exec("INSERT INTO `test` (name, surname, age) VALUES ('Иван-$i', 'Петров-$i', 28)");

}

$db->commit(); 

echo $db->lastInsertId(), ' записей';
  
echo '<br>', round(memory_get_usage()/1024, 2) , ' кб, ' , round((microtime(true) - START_TIME),4) , ' c.';
?>

Время выполнения: около 0,9 секунд.

Без транзакций:

<?php
define ('START_TIME', microtime(TRUE));

$db = new PDO('sqlite:db.sqlite3');

$db->exec('CREATE TABLE `test` (
         id INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
         name VARCHAR(255)  NOT NULL,
         surname VARCHAR(255)  NOT NULL,
         age NUMERIC  NOT NULL
   )');
	
for ($i = 1; $i <= 10000; $i++) {

	$db->exec("INSERT INTO `test` (name, surname, age) VALUES ('Иван-$i', 'Петров-$i', 28)");

}

echo $db->lastInsertId(), ' записей';
  
echo '<br>', round(memory_get_usage()/1024, 2) , ' кб, ' , round((microtime(true) - START_TIME),4) , ' c.';
?>

Время выполнения: около 370 секунд.

Превосходство в 400 раз! Так что если нужно выполнить запись несколькими запросами, лучше использовать транзакции.

Сравнение времени выборки из бд.

Тестовый скрипт:

<?php
define ('START_TIME', microtime(TRUE));

$db = new PDO('sqlite:db.sqlite3');
  
$db->beginTransaction();

for ($i = 5000; $i <= 9000; $i++)
{
	$db->query('SELECT * FROM `test` where name=\'Иван-$i\'');
}

$db->commit(); 

echo '<br>', round(memory_get_usage()/1024, 2) , ' кб, ' , round((microtime(true) - START_TIME),4) , ' c.';
?>

Время выполнения: около 0.35 секунд.

В отличии от записи, время выборки оказалось одинаковым, что с транзакциями, что без. Хотя и так время выполнения вполне приемлимо.

Ссылки по теме:
sql-school.info
intuit.ru
ru2.php.net

Комментарии (RSS)

Оставить комментарий: