为什么 `ON (fts.text MATCH 'word' AND fts.id = item.id)` 和 `...WHERE fts.text MATCH 'word'` 有相同的查询计划?

问题描述 投票:0回答:0

我有一个典型的小型 sqlite 数据库,有 3 个表,一个用于项目(这是漫画,有

id
s),另一个用于标签(
|id|name|
),另一个用于它们之间的关联(
|tag_id| manga_id|
)所以现在我需要一种方法来按标题搜索项目并获取它们 with 标签。有点像这样:

| title     | author          | tags                    |
|-----------+-----------------+-------------------------|
| Mushishi  | Shuichi Shigeno | supernatural, fantasy   |
| Initial D | Yuki Urushibara | racing, sports, deja vu |

所以我也决定使用sqlite内置的fts虚表。它包含的所有内容都是漫画标题及其 ID。

我实际上设法提出了一个查询,但我对此很谨慎:

SELECT manga.title, GROUP_CONCAT(tag.name) tags FROM manga
JOIN mangafts fts ON fts.manga_id = manga.id
JOIN manga_tag_association ass ON ass.manga_id = manga.id
JOIN tag ON tag.id = ass.tag_id
WHERE fts.title MATCH 'mushishi' GROUP BY manga.id;

因为我除了先查fts表,然后根据查到的ids进行join,但是查询计划如下:

QUERY PLAN
|--SCAN manga
|--SEARCH ass USING AUTOMATIC COVERING INDEX (manga_id=?)
|--SEARCH tag USING INTEGER PRIMARY KEY (rowid=?)
`--SCAN fts VIRTUAL TABLE INDEX 3:

我尝试将查询更改为此

SELECT manga.title, GROUP_CONCAT(tag.name) tags FROM manga
JOIN mangafts fts
  ON (fts.title MATCH 'mushishi' AND fts.manga_id = manga.id)
JOIN manga_tag_association ass ON ass.manga_id = manga.id
JOIN tag ON tag.id = ass.tag_id
GROUP BY manga.id;

然而查询计划完全一样。

其实我有几个问题:

  1. 为什么要扫描
    manga
    表,为什么要先扫描?
  2. 为什么不先扫描fts表?我的全部目的是加快搜索速度。
  3. 根据我的需要,我做错了什么吗?
sql sqlite full-text-search fts4
© www.soinside.com 2019 - 2024. All rights reserved.