PHP / SQLite - копирование таблицы с диска в память - PullRequest
8 голосов
/ 21 июля 2009

У меня есть база данных sqlite3 на моем жестком диске (file.db) с 5 таблицами. Я хотел бы скопировать 3 из этих таблиц в базу данных в памяти (: memory:).

Есть ли простой способ сделать это, используя формат PDO в PHP5?

Ответы [ 5 ]

11 голосов
/ 21 июля 2009

Не специфичное для pdo решение, которое может быть или не быть достаточным в вашем случае:

  • создать: память: база данных
  • Прикрепить существующий файл базы данных
  • СОЗДАТЬ ТАБЛИЦУ ... КАК ВЫБРАТЬ * ИЗ ...
  • Отсоединение файла базы данных

редактировать: пример
Сначала пример базы данных, хранящейся в mydb.sq3

<?php
$pdo = new PDO('sqlite:mydb.sq3');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec('CREATE TABLE foo(x INTEGER PRIMARY KEY ASC, y, z)');

$stmt = $pdo->prepare("INSERT INTO foo (x,y,z) VALUES (:x,:y,:z)");
$stmt->bindParam(':x', $x);
$stmt->bindParam(':y', $y);
$stmt->bindParam(':z', $z);

for($x=0; $x<100; $x++) {
    $y = $x*2;
    $z = $x*2+1;
    $stmt->execute();
}

Теперь у нас есть: memory: база данных и мы хотим передать таблицу foo

<?php
$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec('ATTACH "mydb.sq3" as filedb');
$pdo->exec('CREATE TABLE bar AS SELECT * FROM filedb.foo');
$pdo->exec('DETACH filedb');

Готово. Но давайте посмотрим на таблицу sqlite_master

foreach($pdo->query('SELECT sql FROM sqlite_master') as $row) {
    echo $row['sql'];
}

это печатает

CREATE TABLE bar(x INT,y,z)

Декларация INTEGER PRIMARY KEY ASC потеряна. Может быть достаточно, хотя ....

4 голосов
/ 02 августа 2009

Если это то, что вам нужно сделать, то ответ VolkerK - тот, который я бы предоставил, но я чувствую, что должен указать, что вы будете читать содержимое этих таблиц в память каждый раз, когда запускаете код (каждый раз, когда страница загружается?), поэтому может быть лучше просто запросить файлы данных с диска.

1 голос
/ 03 февраля 2010

Обратите внимание, что всегда можно использовать какой-либо механизм совместной памяти (например, APC, memcache и т. Д.) Для сохранения постоянных баз данных sqlite в памяти при подключении.

0 голосов
/ 19 октября 2016

Использование метода, описанного VolkerK, примерно удвоило производительность моего кода при использовании базы данных sqlite ~ 150 МБ.

Загрузка базы данных в базу данных sqlite в памяти не требовала никаких других изменений в моем существующем коде.

В моем случае использовались данные пакетной обработки, поэтому мне не приходилось сталкиваться с проблемами, которые выделяет Вез Фарлонг.

Чтение данных в память было удивительно быстрым. Целые 150 МБ были загружены в память с SSD менее чем за две секунды. Это казалось слишком хорошим, чтобы быть правдой, поэтому я проверил и перепроверил данные.

Большое спасибо VolkerK за волшебное решение!

Я также обнаружил, что при индексации таблиц в памяти мои запросы выполнялись в три раза быстрее

//adapting VolkerK's example...
//loop through tables from the local sqlite db 
$tables = array('companies', 'directors',  'previous_names');
foreach($tables as $table){
    //load each table into memory
    $pdo->exec("CREATE TABLE $table AS SELECT * FROM filedb.$table");

    //index each table on the relevant columns
    $pdo->exec("CREATE INDEX IF NOT EXISTS `".$table."_company_number` 
                ON $table (`company_number`);");
}
0 голосов
/ 17 января 2013

Вы можете сбросить базу данных в конце соединения, сохранить ее как переменную apc, а затем загрузить и снова запустить из apc в начале следующего выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...