我有很多这样的SQL查询:
SELECT o.Id, o.attrib1, o.attrib2
FROM table1 o
WHERE o.Id IN (
SELECT DISTINCT Id
FROM table1
, table2
, table3
WHERE ...
)
这些查询必须在不同的数据库引擎(MySql,Oracle,DB2,MS-Sql,Hypersonic)上运行,因此我只能使用常见的SQL语法。
Here我读过,使用MySql时IN
语句未经优化且速度非常慢,所以我想将其切换为JOIN
。
我试过了:
SELECT o.Id, o.attrib1, o.attrib2
FROM table1 o, table2, table3
WHERE ...
但这并未考虑DISTINCT
关键字。
问题:如何使用JOIN
方法摆脱重复的行?
答案 0 :(得分:4)
要使用JOIN编写此内容,您可以使用内部选择并加入:
SELECT o.Id, o.attrib1, o.attrib2 FROM table1 o
JOIN (
SELECT DISTINCT Id FROM table1, table2, table3 WHERE ...
) T1
ON o.id = T1.Id
我不确定这会更快,但也许......你可以亲自试试。
通常,仅将自己限制为可在多个数据库上运行的SQL不会产生最佳性能。
答案 1 :(得分:2)
但这没有考虑到 DISTINCT关键字。
您不需要子查询中的distinct
。 in
将返回外部查询中的一行,无论它是否匹配子查询中的一行或一百行。因此,如果您想提高查询的性能,那么distinct
将是一个良好的开端。
调整in
子句的一种方法是使用exists
重写它们。根据数据的分布,这可能会更高效,或者可能更慢。通过调整,基准是王道。
SELECT o.Id, o.attrib1, o.attrib2
FROM table1 o
WHERE EXISTS (
SELECT Id FROM table1 t1, table2 t2, table3 t3 WHERE ...
AND ( t1.id = o.id
or t2.id = o.id
or t3.id = o.id
)
不了解您的业务逻辑,额外过滤器的精确配置可能是错误的。
顺便提一下,我注意到外部查询和子查询都有table1
。如果这不是将您的实际SQL转录到此处的错误,您可能需要考虑这是否有意义。最好避免两次查询该表;使用exists
make可以更轻松地避免双击。
答案 2 :(得分:0)
SELECT DISTINCT o.Id, o.attrib1, o.attrib2
FROM table1 o, table2, table3
WHERE ...
虽然如果您需要支持许多不同的数据库后端,您可能希望在数据层中为每个数据库后端提供一组自己的存储库类,这样您就可以针对每个数据库优化查询。这也使您能够持久存储在其他类型的数据库,xml或Web服务中,或者在需要的任何时候出现。
答案 3 :(得分:0)
我不确定你真的明白你的问题是什么。你为什么不试试这个:
SELECT distinct o.Id, o.attrib1, o.attrib2
FROM
table1 o
, table o1
, table o2
...
where
o1.id1 = o.id
or o2.id = o.id