SQLite和大型交易

时间:2018-08-20 08:31:09

标签: sqlite

我在Unity 3D中有一个项目,并且正在使用针对Android,OSX,iO和Windows的预编译SQLite库。 在Android上使用大笔交易时,我的数据库文件可以从1MB增长到1GB。

例如,在OSX上执行此操作的行为不相同,数据库不会变得太大。在完成事务之前,我会收到“磁盘I / O错误”。 我试图通过比较不同的PRAGMA语句来解决这个问题,但找不到任何东西。

我可能丢失了一些东西,但我不知道什么。

编辑:我已经运行了sqlite3_analyzer,我得到了 Size of the file in bytes......................... 3715072 但磁盘上的文件大小约为1GB

这是发生错误的SQL查询的样子

                                CREATE TEMPORARY TABLE LogRange AS
            SELECT
                l.EntityKey AS EntityKey,
                l.TableName AS TableName,
                l.OrderNumber AS StartOrderNumber,
                l2.OrderNumber AS EndOrderNumber
            FROM IncomingLog AS l 
            INNER JOIN IncomingLog l2 ON l2.OrderNumber > l.OrderNumber AND l2.EntityKey = l.EntityKey AND l2.TableName = l.TableName AND l2.Type = 2
            WHERE l.Type = 0;

            DELETE FROM IncomingLog WHERE Id IN 
            (
                SELECT l.Id
                FROM IncomingLog l
                INNER JOIN LogRange lr ON lr.EntityKey = l.EntityKey AND lr.TableName = l.TableName AND l.OrderNumber >= lr.StartOrderNumber AND l.OrderNumber <= lr.EndOrderNumber
            );
            DROP TABLE LogRange;

            CREATE TEMPORARY TABLE CompressedLog AS
            SELECT
                l.*
            FROM IncomingLog l
            LEFT JOIN 
            (
                SELECT
                    1 as Id,
                    EntityKey,
                    TableName,
                    MAX(OrderNumber) as OrderNumber
                FROM IncomingLog WHERE Type = 1 OR Type = 2
                GROUP BY EntityKey 
            ) updateOrDeleteLogs ON updateOrDeleteLogs.OrderNumber > l.OrderNumber AND updateOrDeleteLogs.EntityKey = l.EntityKey AND updateOrDeleteLogs.TableName = l.TableName
            WHERE ((l.Type=1 OR l.Type = 2) AND updateOrDeleteLogs.Id IS NULL) OR l.Type = 0;

            DELETE FROM IncomingLog;
            INSERT INTO IncomingLog SELECT * FROM CompressedLog;

            DROP TABLE CompressedLog;

这就是IncomingLog表的样子

CREATE TABLE IncomingLog (OrderNumber INTEGER PRIMARY KEY AUTOINCREMENT, Id TEXT NOT NULL COLLATE NOCASE, Type INETEGER, CreationDate DATETIME, EntityType TEXT, EntityKey TEXT, TableName TEXT, Data TEXT)

数据列存储json,因此可能会占用大量空间。 在我的示例中,IncomingLog表中有5000行。

我已经为包装库实现了扩展错误代码,现在我得到了SQLITE_IOERR_GETTEMPPATH(6410)。 所以现在我必须为此找到解决方案。

1 个答案:

答案 0 :(得分:0)

我找到了问题和解决方案。 显然,Android上的SQLite找不到临时目录,这就是我收到此错误的原因。 我发现的唯一解决方法是设置PRAGMA temp_store_directory。 唯一的问题是PRAGMA temp_store_directory已过时,但我找不到其他解决方案。

关于为什么数据库增长到1GB的原因,我仍然没有答案。