为什么子查询在静态列表没有时会导致扫描?

got*_*o10 10 sql sqlite

我有一个包含子查询的查询,该子查询总是导致一个非常大的表的SCAN导致查询时间很短.

这是我正在使用的查询:

SELECT PersonId 
  FROM person 
 WHERE PersonId IN (
                    SELECT PersonId 
                      FROM relationship 
                     WHERE RelatedToPersonId = 12270351721
                   );
Run Code Online (Sandbox Code Playgroud)

查询计划报告为:

SCAN TABLE person (~100000 rows)
EXECUTE LIST SUBQUERY 1
SEARCH TABLE relationship USING INDEX relationship_RelatedToPersonId_IDX (RelatedToPersonId=?) (~10 rows)
Run Code Online (Sandbox Code Playgroud)

具有静态列表的相同查询(相当于子查询的结果):

SELECT PersonId 
  FROM person 
 WHERE PersonId IN (12270351727,12270351730,12270367969,12387741400);
Run Code Online (Sandbox Code Playgroud)

以及查询计划:

SEARCH TABLE person USING COVERING INDEX sqlite_autoindex_person_1 (PersonId=?) (~5 rows)
EXECUTE LIST SUBQUERY 1
Run Code Online (Sandbox Code Playgroud)

如果第二个查询没有,为什么第一个查询会提示扫描?

dmo*_*gle 2

必须扫描该表,因为您在子查询的 WHERE 子句中包含另一个字段 (RelatedToPersonId)。PersonID 列表可以直接进入索引。