PHP / SQLite – копирование таблицы с диска в память

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

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

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

  • создать: память: база данных
  • Прикрепить существующий файл базы данных
  • CREATE TABLE … AS SELECT * FROM …
  • Отсоединить файл базы данных

edit: пример
Сначала пример базы данных, хранящейся в 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: database и хотите перенести таблицу 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 теряется. Может быть достаточно, хотя ….

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

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

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

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

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

Моим вариантом использования были данные пакетной обработки, поэтому мне не приходилось сталкиваться с проблемами, которые выделяют Wez Furlong.

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

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

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

 //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`);"); }