sql - 使用 OR 术语在 sqlite/JOIN 中进行高效的变体记录选择

标签 sql join sqlite

我有一个数据记录应用程序,使用 sqlite3 来存储共享公共(public) header 的不同类型的记录。

我将标题放在一个表中,并为每个变体的详细信息创建了单独的表。

明细表中的rowid是表头的rowid。 header rowid 仅显示在其中一个详细信息表中(针对该变体)。

我想在单个查询中获取多种类型的记录。 也就是说,我希望 Sqlite 对 headers 表进行索引搜索以查找一组工作记录,然后使用该组 id 通过 rowid 对变体详细信息进行快速二进制获取。所以:

SELECT * FROM headers JOIN headers 
ON headers.id = variant1.id OR headers.id = variant2.id
WHERE some_header_condition

SELECT * FROM headers JOIN headers
ON headers.id IN (variant1.id, revariant2.id )
WHERE some_header_condition

这是可行的,但是当在 JOIN 谓词中遇到 OR 术语时,sqlite3 会对详细信息表variant1和variant2进行全表扫描,而不是仅仅通过 rowid 外键获取适当的记录。

类似于:

0     0              2     SCAN TABLE variant2 (~5900 rows)
0     1              1     SCAN TABLE variant1 (~26588 rows)
0     2              0     SEARCH TABLE headers USING INTEGER PRIMARY KEY (rowid=?) (~2 rows)
0     0              0     EXECUTE LIST SUBQUERY 1

我可以通过执行以下技巧来强制二分搜索:

SELECT header.f1, variant1.f, NULL FROM header JOIN header.id = variant1.id ...
UNION ALL
SELECT header.f1, NULL, variant2.f FROM header JOIN header.id = variant2.id ...

但是头表被访问了两次。

我还可以想象将 header.id 选择到临时表中,并使用其中的 ids 来获取详细信息。

或者...我可以将整个困惑状态去标准化。

但是所有这些解决方法都非常不方便。所以我的问题是,是否有一个很好的 JOIN 查询可以一次性获取这些变体,而无需进行表扫描?

最佳答案

尝试使用外连接:

SELECT *
FROM headers
  LEFT JOIN variant1 ON headers.id = variant1.id
  LEFT JOIN variant2 ON headers.id = variant2.id
WHERE headers...

产生这样的计划:

sele  order  from  deta
----  -----  ----  ----
0     0      0     SEARCH TABLE headers USING INTEGER PRIMARY KEY (rowid>? AND rowid<?) (~31250 rows)
0     1      1     SEARCH TABLE variant1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
0     2      2     SEARCH TABLE variant2 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)

关于sql - 使用 OR 术语在 sqlite/JOIN 中进行高效的变体记录选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12940221/

相关文章:

ios - 下载低版本pod文件

python - 如何使用 pandas.read_sql 中的参数在日期之间从 SQLite 表中使用 Python pandas 导入数据

mysql - 在一个查询中从单个 mysql 表中选择行和总和

sql - 如何从返回多行的 SELECT 中创建一个数组

mysql - 如何根据不同服务器中不同数据库中存在的表在服务器中的数据库中创建 View ?

php+mysql,使用 "join"时出现汉字乱码

MySQL 显示存在于一个表中但不存在于另一个表中的行

SQL:如何获取 XML 数据类型中的属性值?

mysql - 内连接 : add up amounts with same id

java - 在 Android 上的 SQLite 数据库中重置 AUTOINCREMENT?