Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 当存在NULL时,选择与另一个表中的项不匹配的行的性能_Sql_Sqlite - Fatal编程技术网

Sql 当存在NULL时,选择与另一个表中的项不匹配的行的性能

Sql 当存在NULL时,选择与另一个表中的项不匹配的行的性能,sql,sqlite,Sql,Sqlite,相关问题: 我试图使用此方法选择行,但无法使其在SQLite中工作。经过一番争论,我突然想到,原因可能是某些字段中存在空值。果然,我是对的,当我在下面的查询中将=更改为IS时,事情开始按预期运行: CREATE TEMP TABLE newEvent(id INTEGER,t INTEGER,name,extra,extra2,extra3); INSERT INTO newEvent(id,t,name,extra,extra2,extra3) VALUES

相关问题:

我试图使用此方法选择行,但无法使其在SQLite中工作。经过一番争论,我突然想到,原因可能是某些字段中存在空值。果然,我是对的,当我在下面的查询中将
=
更改为
IS
时,事情开始按预期运行:

CREATE TEMP TABLE newEvent(id INTEGER,t INTEGER,name,extra,extra2,extra3);
INSERT INTO newEvent(id,t,name,extra,extra2,extra3) VALUES
                           (0, 1376351146, 'TEST', NULL, NULL, NULL),
                           (0, 1376348867, 'OLD', NULL, NULL,NULL);
SELECT n.id,n.t,n.name,n.extra,n.extra2,n.extra3 FROM newEvent n 
       LEFT JOIN event E ON n.t = E.t AND n.name IS E.name
                                      AND n.extra IS E.extra;
                                      AND n.extra2 IS E.extra2;
                                      AND n.extra3 IS E.extra3
       WHERE E.id IS NULL;
DROP TABLE newEvent;
在上面的示例中,表
event
中有一条记录,其
name='OLD'
newEvent
表的定义与原始
event
表相同

然而,我注意到一个大问题:我的查询现在运行几乎需要30秒!如果我只将
n.name IS E.name
更改为
n.name=E.name
,但保留所有其他
IS
的原样,那么查询只需要大约400毫秒。(表
event
中约有300万条记录)

为什么性能有这么大的差异?事实证明,对于
名称
比较,我实际上可以使用
=
而不是
IS
,因为它从来都不是空的,但如果它曾经是空的,它似乎会中断。相反,我担心在某个时候查询可能会开始运行缓慢,因为我不明白是什么让平等查询运行得如此之快。我的猜测是,也许SQLite不知何故知道额外字段中有空值,并且能够进行优化,但我希望有比胡乱猜测更坚定的东西


据我所知,
IS
只是
=
,还有一个附加条件,即它将把空比较视为空字符串(假设没有实际的空字符串进行比较)。那么,为什么在名称字段上使用
=
的速度要快75倍,但对额外字段的性能没有影响呢?

在连接中,SQLite可以通过索引查找优化
=
,但不能优化
is
。 此外,在单个查询中,每个表不可能使用多个索引

因此,要么您没有同时包含
name
extra
*的多列索引,要么额外列的选择性不够高

您可以使用以下命令尝试完全不同的查询:


但是,这不允许您获得未比较的列(如
id
)。

为什么不比较
id
列?要匹配的行是否会有所不同?@Andriy name和其他字段都是非类型化的(类型对SQLite来说更像是“建议”)。Name始终是一个字符串,而extra则是string、number和NULL。它确实有区别,因为SQLite不会将“200”匹配为等于200,例如。@CL我不匹配该行,因为它是自动的,在插入之前我不知道它。我基本上是在试图防止同一条记录被插入两次(在我使用的体系结构中,在极少数情况下是可能的)。其他字段足以唯一标识记录。谢谢,我不知道非类型化列的事情,这是SQLite的一个奇怪方面。(并删除我特别吵闹的第一条评论。)奇怪的是,名字上没有索引,也没有额外的字段。。。然而,在t字段上有一个。
SELECT t, name, extra, extra2, extra3 FROM newEvent
EXCEPT
SELECT t, name, extra, extra2, extra3 FROM event