从大型SQLite数据库中删除列时出现问题

时间:2010-11-01 03:08:51

标签: sqlite

我有一个15gb的SQLite数据库,有40列。我想删除大多数列以使查询更快,数据库更便携。我找到了这个guidance,但无法让它发挥作用。它似乎挂了,我最终破坏了数据库,不得不重新开始。这是我使用的脚本:

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;

有更好的方法吗? FWIW,我有原始的.csv文件,并使用R。

中的RSQLite包导入它

有没有办法只能导入.csv文件中的列子集?谢谢! (SQLite新手)

1 个答案:

答案 0 :(得分:1)

我实际上不知道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子句来获取一个自动收报机MSFTIBM)等符号。

不要删除测试运行中的任何表。


我刚刚注意到insert...select语句的相当奇怪的语法,其中包含列名类型。我不知道这是否是SQLite的扩展,但我认为这会给我熟悉的其他DBMS带来问题。这是你的错字吗?