2012-02-25 160 views
0

我需要做一张表的笛卡尔积,但没有相同的行。现在我有:如何优化笛卡尔积

select * 
From T_Car C1 
Join T_Car C2 On C1.CarID <> C2.CarID 

但是对于1300行的T_Car表需要2分钟的时间。 我试过使用OPTION(HASH JOIN)和OPTION(MERGE JOIN),但是最后出现错误:

查询处理器由于此查询中定义的提示而无法生成查询计划。重新提交查询而不指定任何提示,也不使用SET FORCEPLAN。

有没有可能优化此查询?

+3

你知道如何吓跑许多结果,将返回? (如果我没有弄错,则为169万行)。明显的优化是:不要选择那么多东西。 – delnan 2012-02-25 12:38:58

+0

@delnan,有一个where子句,我相信它只会是1,687,400 :-)。你为什么要做笛卡尔产品?您的问题可能有更好的解决方案。 – Ben 2012-02-25 13:03:30

+0

@Ben我最初占了这一点,但采用大多数舍入方法,结果保持不变;) – delnan 2012-02-25 13:10:17

回答

0

如果您不想加入每一行,可以使用INNER JOIN或LEFT JOIN。一个内部JOIN只返回匹配的行,一个左连接返回左表的空行。右连接返回右表的空行。

1

请您详细说明原因吗? 您提到的查询不是一个常见的(从我的经验),它会导致一个昂贵的查询计划。如果我们能够更好地理解查询的上下文,我们可以采用一种不同的方法来提高性能,也许查询一个存储过程执行多个步骤来检索相关数据,但是对每个阶段。

一个很好的例子(使用你的场景)将创建一个过程,将相关ID隔离到临时表,然后加入它(使用'='而不是'<>')来获得结果。

+0

我想在T_Car表中找到类似的行。所以我需要与其他人比较一排。 – PsCraft 2012-02-25 13:01:24

+0

当你说类似的时候,我猜你想谈谈希望比较表中的其他列吗?是这样吗? – itayw 2012-02-25 13:11:06

+0

@ user927524请定义“相似” - 这里没有人有任何线索你的意思。 – 2012-02-25 14:23:40

0

生产整个笛卡尔产品需要多长时间?其中有1,690,000行?

如果这是一段合理的时间,那么考虑使用MINUS运算符来消除主键匹配的行。就像是。

select * From T_Car C1, T_Car C2 
MINUS 
select * From T_Car C1 Join T_Car C2 On C1.CarID = C2.CarID 

很可能整个笛卡尔产品的生产时间太长。无论如何,你为什么需要这样的结果?也许有更好的方法来建模你的数据。

+1

请注意,如果我没有弄错,SQL Server使用EXCEPT而不是MINUS(来自Oracle)。 – itayw 2012-02-25 13:12:50