2010-11-01 8 views
0

J'ai une base de données SQLite de 15 Go avec 40 colonnes. Je voudrais supprimer la plupart des colonnes pour faire des requêtes plus rapidement et la db plus portable. J'ai trouvé ce guidance, mais je n'arrive pas à le faire fonctionner. Il semble que ça se bloque et je finis par corrompre le db et avoir à recommencer. Voici le script que j'utilise:Problème de suppression des colonnes de la grande base de données SQLite

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; 

Y a-t-il une meilleure façon de procéder? FWIW, j'ai le fichier .csv d'origine et l'importe en utilisant le paquet RSQLite dans R.

Y at-il un moyen que je peux seulement importer un sous-ensemble de colonnes dans un fichier .csv? Merci! (Nouveau à SQLite)

+1

Importer uniquement le sous-ensemble dont vous avez besoin est le chemin à parcourir. Cela devrait être possible. Comment exactement importer le fichier CSV maintenant? – Thilo

+0

@Thilo - J'utilise une fonction d'un paquet R, mais cela ne vous permet pas de limiter le nombre de colonnes à importer. C'est une compétence que j'utiliserai probablement dans les années à venir, donc j'aimerais vraiment apprendre la bonne façon. –

+1

Avez-vous un lien vers cette fonction? Peut-être qu'il est facile de faire une nouvelle fonction qui saute certaines colonnes. – Thilo

Répondre

1

je fait aucune idée si 15G est une grande taille pour SQLite - J'ai tendance à utiliser DMBS » où 15G peut être considéré comme une table de configuration :-)

Cependant, une chose que nous normalement faire pour ce genre de travail, ce qui peut vous aider:

  • la mise hors ligne de base de données totalement (en d'autres termes, empêcher quiconque de connexion et/ou modifier les données) * un. Renommez la table en cours en table de sauvegarde.
  • créer une nouvelle table avec le nom d'origine et le schéma réduit.
  • copier vos données dans la sauvegarde, mais avec deux réserves: d'abord, désactiver les index, les déclencheurs et/ou les contraintes, d'autre part, ne le faites pas dans le cadre d'une transaction (savoir les données sont bonnes car il provient d'une table avec les contraintes, et vous n'avez pas besoin d'une transaction (avec ses frais généraux associés, puisque vous êtes le seul à utiliser la base de données)
  • enfin, ré-installez les index/triggers/contraintes et rouvrez la base de données pour les entreprises.

* a Bien sûr, nous ne faisons pas vraiment faire cela, nous avons plusieurs instances de base de données redondantes avec basculement et toutes sortes d'autres fonctionnalités merveilleuses comme la réplication, mais c'est probablement réalisable pour une petite base de données comme celle-ci.


Une chose que j'ai remarqué est que vous copiez les lignes partielles à la table de sauvegarde, recréez la table d'origine, puis les retransférer ligne par ligne, avant de supprimer la sauvegarde.

Il me semble que vous pourriez simplement renommer la table en cours en celle de sauvegarde au lieu de cette première copie. Peu importe que vous ayez toujours les colonnes inutiles dans la sauvegarde puisque vous ne les transférez pas et finirez par supprimer la table de sauvegarde. Donnez à ce essayer (et minimiser la portée de votre transaction):

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; 

Cela se traduira par une transaction que la moitié de la taille de celui que vous essayez. Puis, et seulement alors, et seulement s'il n'y avait pas d'erreurs, drop dly_backup. Si vous avez toujours des problèmes avec le processus, renommez la table de sauvegarde en drop dly et réessayez.


Une autre chose que vous pouvez essayer est de limiter les données transférées dans un essai, pour voir si elle fonctionne bien avec un ensemble plus restreint de données. En utilisant votre code original, essayez de créer la table dly_backup mais copiez uniquement sur un sous-ensemble de données (en supposant que ce soit NYSE/NASDAQ, vous pouvez utiliser une clause where pour obtenir un seul symbole tel que MSFT ou IBM).

Ne pas supprimer des tables dans le test.


Et je viens de remarquer votre syntaxe assez étrange pour la déclaration insert...select où vous avez à la fois le nom de colonne et le type. Je ne sais pas si c'est une extension pour SQLite mais je pense que cela causerait des problèmes pour d'autres SGBD que je connais. C'était une faute de frappe de votre part?

+0

Cette db est locale seulement. Je ne peux pas comprendre pourquoi ce script se bloque. Il semble que ce soit une tâche VRAIMENT simple, même pour une base de données SQLite de 15gb, donc je peux comprendre pourquoi cela ne fonctionnera pas. –

+1

comment savez-vous que le script est accroché et pas encore en cours? –

+0

Merci! Le nom et le type en étaient la cause. Mais c'est toujours très lent (environ une heure). La prochaine fois que je dois faire cela, je vais essayer le truc 'ALTER', ce qui peut faire gagner du temps. Assez curieusement, même sans les colonnes supprimées, le fichier est toujours 15gb. Merci! –

Questions connexes