为什么在内存模式下不要在sqlite中加速

时间:2016-07-08 07:19:11

标签: sqlite optimization in-memory-database sql-execution-plan

有一个扫描全表的查询,有500万条记录,大约需要60s。如何优化这个? 我曾尝试使用sqlite的内存模式,理论上这应该更快,因为整个数据库都存储在memroy中。但是,它的成本几乎相同。 像这样的表模式:

IF @SkipRows <= 0
    THEN BEGIN
            SELECT  TOP (@TakeROws) *
            FROM    <table>
            WHERE   <predicate>  
            ORDER BY 
             /* some case statement */    
         END
    ELSE BEGIN
            SELECT  *
            FROM    <table>
            WHERE <predicate>
            ORDER BY /*some case statement*/
            OFFSET @SkipRows FETCH NEXT @TakeRows ONLY
         END
    END

这是查询,需要连接3个表的查询:

CREATE TABLE tbl0(estimateid int, seq int,  field1 int NULL, field2 int NULL,  field3 int NULL,  field4 int NULL);
CREATE INDEX tbl0_idx on tbl0(estimateid);
CREATE TABLE tbl1(seq int, companyid int, field1 int NULL, field2 int NULL,  field3 int NULL,  field4 int NULL, field5 int NULL);
CREATE INDEX tbl1_idx on tbl1(seq);
CREATE TABLE tbl2(symbolid int, relatedcompanyid int,  value char(64),  field1 int NULL, field2 int NULL,  field3 int NULL,  field4 int NULL, field5 int NULL);
CREATE INDEX tbl2_idx on tbl2(relatedcompanyid);

如何加快此查询?似乎不可避免地会有一张桌子被完全扫描。每个表包含大约500万条记录,此查询需要很长时间(几分钟)。 当我把db放在内存中时,使用这个#sqlite3:memory:,它的速度没有任何区别。 非常感谢帮助。

2 个答案:

答案 0 :(得分:1)

完整索引扫描(类型:索引)根据文档是您选择的全表扫描之后的第二个可能最差的执行计划。

全表扫描是数据库的资源密集型操作,除非你提高内存,CPU速度,索引表,减少记录数等等,否则幕后没有魔法。这就是为什么你没有当你把所有东西都搬到记忆中时,注意到任何急剧的速度增加。

您应该尝试避免这种情况并进行更好的查询,或者优化数据库和表结构。请参考EXPLAIN QUERY PLANQuery Planning以获取有关SQL执行及其优化方式的更多详细信息。

很难说更多更具体,因为在您的原始问题中,您没有提供数据库结构,数据特征,查询等。

答案 1 :(得分:0)

您的数据库不在内存中;你做错了什么。我构建了一个程序,在另一个内存数据库系统中加载了500万条记录,完整的顺序扫描花了不到800毫秒。即使SQLite只是我使用的内存数据库系统的一半,它也只需要一两秒钟。

另一种可能性是你在获取每一行或执行其他逻辑后写入控制台,导致整体缓慢。