Sql 为什么此子查询比内部联接快10倍

Sql 为什么此子查询比内部联接快10倍,sql,sqlite,Sql,Sqlite,我有两个表ecdict和favorite,还有一个视图,它们只是内部连接了两个表 CREATE TABLE ecdict('_id' INTEGER PRIMARY KEY, 'word' VARCHAR NOT NULL UNIQUE, 'meaning' VARCHAR, 'phonetic_string' VARCHAR, 'example' VARCHAR); CREATE TABLE favourite('_id' INTEGER PRIMARY KEY, 'word' VARCHAR

我有两个表ecdict和favorite,还有一个视图,它们只是内部连接了两个表

CREATE TABLE ecdict('_id' INTEGER PRIMARY KEY, 'word' VARCHAR NOT NULL UNIQUE, 'meaning' VARCHAR, 'phonetic_string' VARCHAR, 'example' VARCHAR);
CREATE TABLE favourite('_id' INTEGER PRIMARY KEY, 'word' VARCHAR NOT NULL UNIQUE);

CREATE VIEW favourite_word as select ecdict.* from ecdict INNER JOIN favourite ON ecdict.word = favourite.word;
以下是结果的执行时间:
时间:0.010

select ecdict.* from ecdict where word in (select word from favourite);
时间:0.226

select * from favourite_word;

为什么他们有如此大的不同?如果它与查询计划有关,为什么sqlite会选择较慢的计划?如何引导sqlite选择更快的一个?谢谢

您需要查看查询计划以了解实际情况。以下是(知情的)猜测

当有一个包含两组索引的内部联接时,基本上有两种可能的查询计划:

  • 扫描
    法令
    表格,使用
    收藏夹.word上的索引在
    收藏夹
    中查找单词
  • 扫描
    收藏夹
    表格,使用
    法令(word)
    上的索引在
    法令
    中查找单词。当有匹配项时,在
    edit
    中查找记录
  • (唯一的约束将创建索引。)

    所有这些都是相等的——也就是说,没有关于表大小的信息——在这种情况下,首选第一种方法。为什么?因为没有查找附加列的附加步骤


    当您在
    中使用
    表达查询时,我认为SQLite将始终使用第一种方法。在本例中,我猜测
    最喜欢的
    表比
    法令
    表小得多,因此第二种方法实际上更好。当您将查询编写为一个
    连接时
    ,会考虑这两种可能性,并选择更好的一种。

    是的,Favorite要小得多。但是sqlite不会为我选择更快的吗?@Bear。它将用于显式的
    连接
    。但是
    中的
    将集中在
    收藏夹
    上的索引上。它可以考虑另一个方向,但这是一个非常特殊的情况,因为这两个列都被声明为唯一的。非常感谢。但是如果explict join能为我找到一个更好的,它应该选择第二个approach@Bear . . . 显式的
    join
    似乎选择了第二个选项。感谢您的帮助。但我真的很想知道更多。例如,为什么它会选择较慢的一个,以及如何让sqlite选择较快的一个。我已经更新了这个问题。