我有三个表,表3基本上是表1和表2的中间表。当我执行包含“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
1条答案
按热度按时间5sxhfpxr1#
from table1, table3
在大多数数据库中是交叉连接,由于数据的大小,交叉连接是巨大的,但在sqlite3中它是一个内部连接。从sqlite中选择docs旁注:交叉连接的特殊处理。“内部联接”、“联接”和“联接”运算符之间没有区别。它们在sqlite中完全可以互换。
在这种情况下,这不是你的问题,但我们不要试探命运;总是显式地写出连接。
因为您只是在计数,所以不需要表1中的任何数据,但是id.table3有table1\u id,所以不需要与table1联接。我们完全可以用table3连接表来实现这一点。
sqlite只能对每个表使用一个索引。要在如此大的数据集上执行此操作,需要两列的复合索引:
table3(table1_id, table2_id)
. 想必您不想要重复的,所以应该采用唯一索引的形式。这将包括对table1\u id的查询以及对table1\u id和table2\u id的查询;您应该删除table1\u id索引以节省空间和时间。对于只使用table2\u id的查询,复合索引不会保留现有的table2\u id索引。
您的查询现在应该运行lickity split。
有关更多信息,请阅读sqlite查询优化器。
太字节就是大量的数据。虽然sqlite在技术上可以处理这个问题,但它可能不是最好的选择。对于小型和简单的数据库来说,它是很好的,但是它缺少很多特性。您应该研究一个更强大的数据库,比如postgresql。它不是一个灵丹妙药,所有相同的原则都适用,但它更适合于这种规模的数据。