NULL或NOT为NULL - 对性能的影响

时间:2018-01-13 20:23:28

标签: sql sqlite

所以我导入大型JSON数据并将其转换为SQLite服务器。我正在使用插入事务,我尝试使用NULL表或不使用NULL来检查性能差异。

当我在SQLite中使用的表格看起来像这样:

CREATE TABLE comments(
    id TEXT, 
    author TEXT, 
    body TEXT, 
    score INTEGER, 
    created_utc TEXT
);

导入时间非常慢,在表格中搜索(例如select = from comments where author ='blabla')也很慢。

当使用具有指定NULL或NOT NULL约束的表时,导入时间和搜索时间变得更快(从2000秒到600秒)。

CREATE TABLE comments(
    id TEXT PRIMARY KEY, 
    author TEXT NOT NULL, 
    body TEXT NULL, 
    score INTEGER NULL, 
    created_utc TEXT NULL
);

有没有人知道为什么在使用NULL或NOT NULL时会发生这种性能变化?

1 个答案:

答案 0 :(得分:2)

根据我的评论,添加PRIMARY KEY可能是有关搜索改进的主要因素。虽然它可能会对插入产生负面影响,因为必须维护该索引。

编码NULL没有区别,因为它只是将NOT NULL标志保留为0,因此可以忽略。

由于符合约束,编码NOT NULL可能会导致更少的插入,从而可以提高性能。

关于PRIMARY INDEX,将其编码为INTEGER PRIMARY KEYINTEGER PRIMARY KEY AUTOINCREMENT以外的任何内容将导致创建后续索引。

也就是说,如果表没有用WITHOUT ROWID定义,那么SQLite会创建一个“REAL”主索引,其中包含一个名为 rowid 的通常不可见的列。这唯一标识一行。 (尝试SELECT rowid FROM comments

因此,在两种情况下都有一个基于rowid的索引。对于所有意图和目的,这将是插入行的顺序。

在第二种情况下,将有2个索引基于rowid的“REAL”主索引和基于id列的定义的主索引。由于需要维护第二个索引,因此会对插入产生一些影响。

所以说你在id列中搜索id x,在第一个表中它会相对较慢,因为它必须根据rowid顺序搜索,它就是它的全部。但是,根据id和搜索添加索引将是有利的,因为索引(可用的2)是搜索可能基于的索引。

请注意,上面是一个非常简单的概述,它不考虑可能感兴趣的The SQLite Query PlannerANALYZE statement也可能是有意义的。