Проблема удаления столбцов из большой базы данных SQLite - PullRequest
0 голосов
/ 01 ноября 2010

У меня есть 15 ГБ базы данных SQLite с 40 столбцами.Я хотел бы удалить большинство столбцов, чтобы сделать запросы быстрее и БД более переносимым.Я нашел это руководство , но не могу заставить его работать.Кажется, что он зависает, и я заканчиваю тем, что искажал базу данных и начинал сначала.Вот скрипт, который я использую:

BEGIN TRANSACTION;
CREATE TEMPORARY TABLE dly_backup(DATE INTEGER,
    TICKER TEXT,
    TSYMBOL TEXT,
    VOL INTEGER,
    RET REAL,
    RETX REAL,
    VWRETD REAL,
    VWRETX REAL,
    EWRETD REAL,
    EWRETX REAL,
    SPRTRN REAL
);
INSERT INTO dly_backup SELECT DATE INTEGER,
    TICKER TEXT,
    TSYMBOL TEXT,
    VOL INTEGER,
    RET REAL,
    RETX REAL,
    vwretd REAL,
    vwretx REAL,
    ewretd REAL,
    ewretx REAL,
    sprtrn REAL
    FROM dly;
DROP TABLE dly;
CREATE TABLE dly(DATE INTEGER,
    TICKER TEXT,
    TSYMBOL TEXT,
    VOL INTEGER,
    RET REAL,
    RETX REAL,
    VWRETD REAL,
    VWRETX REAL,
    EWRETD REAL,
    EWRETX REAL,
    SPRTRN REAL
);
INSERT INTO dly SELECT DATE INTEGER,
    TICKER TEXT,
    TSYMBOL TEXT,
    VOL INTEGER,
    RET REAL,
    RETX REAL,
    VWRETD REAL,
    VWRETX REAL,
    EWRETD REAL,
    EWRETX REAL,
    SPRTRN REAL
    FROM dly_backup;
DROP TABLE dly_backup;
COMMIT;

Есть ли лучший способ сделать это?Кстати, у меня есть оригинальный файл .csv, и я импортирую его с помощью пакета RSQLite в R.

Есть ли способ, которым я могу импортировать только подмножество столбцов в файле .csv?Спасибо!(плохо знаком с SQLite)

1 Ответ

1 голос
/ 01 ноября 2010

На самом деле я понятия не имею, является ли 15G большим размером для SQLite - я склонен использовать DMBS ', где 15G можно рассматривать как таблицу конфигурации: -)

Однако, одна вещь, которую мы обычно делаем для этого видаработы, которая может вам помочь:

  • полностью отключить базу данных (другими словами, запретить кому-либо подключение и / или изменение данных) * a .
  • переименуйте текущую таблицу в резервную.
  • создайте новую таблицу с исходным именем и сокращенной схемой.
  • скопируйте в нее данные из резервной копии, но с двумя оговорками: во-первых, отключите все индексы, триггеры и / или ограничения, во-вторых, не делайте это как часть транзакции (вы знаете данные хороши, поскольку они поступают из таблицы с ограничениями, и вымне не нужна транзакция (с соответствующими накладными расходами, поскольку вы используете базу данных только вы).
  • наконец, восстановите индексы / триггеры / ограничения и заново откройте базу данных для бизнеса.

* a Конечно, мы не на самом деле делаем это, у нас есть несколько избыточных экземпляров базы данных с аварийным переключением и все другие замечательные функции, такие какрепликации, но это, вероятно, работоспособно для небольшой базы данных, подобной этой.


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

Мне кажется, что вы можете просто переименовать текущую таблицу в резервную копию вместо этой первой копии.Неважно, что у вас все еще есть ненужные столбцы в резервной копии, поскольку вы не собираетесь их переносить и в конечном итоге удалите таблицу резервных копий.Попробуйте (и сведите к минимуму объем транзакции):

begin transaction;
alter table dly rename to dly_backup;
create table dly (
  date integer, ticker text, tsymbol text, vol integer, ret real, retx real,
  vwretd real, vwretx real, ewretd real, ewretx real, sprtrn real);
commit;

begin transaction;
insert into dly (
    date, ticker, tsymbol, vol, ret, retx,
    vwretd, vwretx, ewretd, ewretx, sprtrn
  ) select
    date, ticker, tsymbol, vol, ret, retx,
    vwretd, vwretx, ewretd, ewretx, sprtrn
  from dly_backup;
commit;

В результате транзакция будет вдвое меньше той, которую вы пытаетесь выполнить.

Тогда и только тогдаи только если не было ошибок, вы бы drop dly_backup.Если у вас все еще были проблемы с процессом, вы бы drop dly переименовали бы таблицу резервных копий в исходную и повторите попытку.


Еще одна вещь, которую вы можете попробовать - ограничить объем передаваемых данных.в тестовом прогоне, чтобы увидеть, работает ли он нормально с меньшим набором данных.Используя свой исходный код, попробуйте создать таблицу dly_backup, но копировать только в подмножество данных (предполагая, что это цитаты NYSE / NASDAQ, вы можете сделать что-то вроде использования where, чтобы получить только один символ тикера, такой как MSFT или IBM).

Не отбрасывать таблицы в тестовом прогоне.


И я только что заметил ваш довольно странный синтаксисдля оператора insert...select, где у вас есть имя типа столбца и .Я не знаю, является ли это расширением для SQLite, но я думаю, что это вызовет проблемы для других СУБД, с которыми я знаком.Это была опечатка с вашей стороны?

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