首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQLite `Ex平原查询计划‘显示的不是每一步吗?

SQLite `Ex平原查询计划‘显示的不是每一步吗?
EN

Stack Overflow用户
提问于 2022-09-30 15:12:54
回答 1查看 97关注 0票数 0

这是一些伪SQL,其中很容易复制“问题”:

代码语言:javascript
复制
create table Child (
    childId text primary key,
    some_int int not null
);

create table Person (
    personId text primary key,
    childId text,
    foreign key (childId) references Child (childId) on delete cascade
);

create index Person_childId on Person (childId);

explain query plan select count(1)
                   from Person
                            left outer join Child on Child.childId = Person.childId
                   where Person.childId is null or Child.some_int = 0;

查询计划的结果是:

代码语言:javascript
复制
SCAN Person USING COVERING INDEX Person_childId
SEARCH Child USING INDEX sqlite_autoindex_Child_1 (childId=?) LEFT-JOIN

这看起来很棒对吧?但我很好奇这是否是“完整”计划。这是因为some_int 没有索引。但是查询计划并没有揭示这一点,我在任何地方都看不到过滤。数据库必须在此字段上筛选,对吗?

当我在单独的查询中执行some_int字段时,它显示了一个SCAN,就像我在上一个查询计划中看到的一样,因为没有索引

代码语言:javascript
复制
explain query plan select * from Child where some_int = 0;

给予:

代码语言:javascript
复制
SCAN Child

现在我的问题是:

  • 为什么在第一个查询计划中没有显示SCAN Child
  • 为什么SCANPerson上而不是SEARCH
  • 第一个查询计划是“快速”还是仍然需要添加索引?
EN

回答 1

Stack Overflow用户

发布于 2022-10-03 08:47:38

你应该看看此页。它深入解释了sqlite查询计划器,您可以找到所有问题的答案。注意,像WHERE some_int=0这样的过滤条件不会显示在查询计划中,因为它们不会影响计划,而只会影响结果集。

简单地说:

为什么在第一个查询计划中没有显示“扫描子”?

因为,由于LEFT JOIN,sqlite需要SCAN Person,并且对于每一行人,使用ChildId上的索引在Child中找到相应的记录。

为什么要对人进行扫描而不是搜索?

SCAN意味着按表的存储顺序读取表的所有行。SEARCH是对表中单个值的查找,使用索引查找rowid,使用rowid查找表的该行,而无需扫描所有te表以找到该行。因为您的查询需要读取所有的Person.childId,所以它会进行完整的扫描。

第一个查询计划是“快速”还是仍然需要添加索引?

您的查询已经使用了它可以使用的所有索引,所以它已经尽可能快地得到它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73910788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档