以下是我数据库相关部分的布局:
(顺便说一句,我用wwwsqldesigner制作了这个图表)
现在,我想查询与A的特定行匹配的所有C行。
我想出的查询是有效的。例如,在C中查找与A的第123行匹配的行:
SELECT C.* FROM C
LEFT JOIN B1 ON (B1.id = C.id_B1)
LEFT JOIN B2 ON (B2.id = C.id_B2)
WHERE B1.id_A = 123 OR B2.id_A = 123
但是,我认为上面的查询效率相当低,因为它会在大集合中收集B1和B2的所有行,然后再将其减少,对吧?
我相信我应该首先对B1和B2进行查询,选择id_A值,然后将这些结果以某种方式连接到匹配的C行。
我已经查看了sqlite.org's docs的SELECT命令,但可能性让我不堪重负。
如何解决这个问题?有点解释解决这个问题的思考过程,我们将不胜感激。
(另外,如果你能为这个问题建议一个更好的标题 - 我真的不知道如何确定这个问题)
答案 0 :(得分:3)
你的方法很好,虽然好像它可能会返回重复项。
您可能会看到其中一个更快:
SELECT C.*
FROM C
WHERE EXISTS (SELECT 1 FROM B1 WHERE B1.id = C.id_B1 AND B1.id_A = 123) OR
EXISTS (SELECT 1 FROM B2 WHERE B2.id = C.id_B2 AND B2.id_A = 123);
这对索引最有效。 " B"中id
的索引表很好,虽然(id, id_A)
会更好。
OR:
SELECT DISTINCT C.*
FROM C JOIN
B1 ON B1.id = C.id_B1
WHERE B1.id_A = 123
UNION
SELECT DISTINCT C.*
FROM C JOIN
B2 ON B1.id = C.id_B2
WHERE B2.id_A = 123;
如果您知道没有重复项,请使用union all
代替union
。
答案 1 :(得分:1)
我认为上面的查询效率相当低,因为它会在大集合中收集B1和B2的所有行,然后再将其减少,对吧?
对于SQLite我可能是错的,但是任何有价值的数据库引擎都应该能够通过找到与B1
子句匹配的B2
和where
中的行来优化查询,所以不,它不会将整个表加载到内存中。
通过使用EXPLAIN QUERY PLAN
添加查询,您可以查看查询使用的计划。只要引擎不在B1
和/或B2
上执行SCAN TABLE,那么查询应该没问题。
请注意,您可以通过在B1.id_A
和B2.id_A
上添加索引来显着提高此查询的性能