sql - 为什么使用“in”和“on”语句进行查询无限运行
问题描述
我有三个表,table3 基本上是 table1 和 table2 的中间表。当我执行包含“in”并连接 table1 和 table3 的查询语句时,它一直在运行,我无法得到结果。如果我使用id=134
而不是id in (134,267,390,4234 ... )
,结果就会出现。我不明白为什么“in”有效果,有人知道吗?
查询语句:
select count(*) from table1, table3 on id=table3.table1_id where table3.table2_id = 123 and id in (134,267,390,4234) and item = 30;
表结构:
table1:
id integer primary key,
item integer
table2:
id integer,
item integer
table3:
table1_id integer,
table2_id integer
-- the DB without index was 0.8 TB after the three indices is now 2.5 TB
indices on: table1.item, table3.table1_id, table3.table2_id
环境:Linux,sqlite 3.7.17
解决方案
from table1, table3
是大多数数据库上的交叉连接,对于数据的大小,交叉连接是巨大的,但在 SQLite3 中它是内部连接。来自SQLite SELECT 文档
旁注: CROSS JOIN 的特殊处理。“INNER JOIN”、“JOIN”和“,”连接运算符之间没有区别。它们在 SQLite 中是完全可以互换的。
在这种特定情况下,这不是您的问题,但我们不要诱惑命运;总是明确地写出你的连接。
select count(*)
from table1
join table3 on id=table3.table1_id
where table3.table2_id = 123
and id in (134,267,390,4234);
由于您只是在计数,因此您不需要 table1 中的任何数据,而是 ID。table3 有table1_id,所以不需要加入table1。我们可以完全使用 table3 连接表来做到这一点。
select count(*)
from table3
where table2_id = 123
and table1_id in (134,267,390,4234);
SQLite 每个表只能使用一个索引。要在如此大的数据集上执行此操作,您需要两列的复合索引table3(table1_id, table2_id)
: . 大概你不想要重复,所以这应该采用唯一索引的形式。这将涵盖仅针对 table1_id 的查询以及针对 table1_id 和 table2_id 的查询;您应该删除 table1_id 索引以节省空间和时间。
create unique index table3_unique on table3(table1_id, table2_id);
复合索引不适用于仅使用 table2_id 的查询,保留现有的 table2_id 索引。
您的查询现在应该运行 lickity-split。
有关更多信息,请阅读SQLite 查询优化器。
1 TB包含大量数据。虽然SQLite 在技术上可以处理这个问题,但它可能不是最佳选择。它非常适合小型和简单的数据库,但它缺少很多功能。您应该研究更强大的数据库,例如PostgreSQL。它不是灵丹妙药,所有相同的原则都适用,但它更适合这种规模的数据。
推荐阅读
- jmeter - 异常:java.lang.ClassCastException:com.blazemeter.jmeter.threads.DynamicThread 无法转换为 org.apache.jmeter.samplers.SampleResult
- gradle - 使用 install4j gradle 任务时出错(无法投射 Install4jExtension_Decorated)
- grammar - * 可以在符号标记中用于多个字符吗?
- sql - 我的日期更改为几位数字组合 - SQL Server
- python - 用树定义的树节点
- ubuntu-18.04 - DBeaver 无法在 Ubuntu 18.04 上启动
- c - 保留源文件路径的问题
- kotlin - 如何在 Kotlin 中的每个函数之后执行定义的函数
- php - 如何回显从数据库中获取的数组中的选定值
- image-processing - RGB 图像中的像素数