Sql 如何优化笛卡尔积

Sql 如何优化笛卡尔积,sql,sql-server,optimization,cartesian-product,Sql,Sql Server,Optimization,Cartesian Product,我需要做一个表的笛卡尔乘积,但是没有相同的行。现在我有: select * From T_Car C1 Join T_Car C2 On C1.CarID <> C2.CarID 选择* 从T_车C1 将T_车C2连接到C1.CarID C2.CarID上 但对于1300行的T_Car表,几乎需要2分钟。 我尝试使用OPTION(哈希连接)和OPTION(合并连接),但最终出现错误: 由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示和不使用SET-FORCE

我需要做一个表的笛卡尔乘积,但是没有相同的行。现在我有:

select * 
From T_Car C1
Join T_Car C2 On C1.CarID <> C2.CarID
选择*
从T_车C1
将T_车C2连接到C1.CarID C2.CarID上
但对于1300行的T_Car表,几乎需要2分钟。 我尝试使用OPTION(哈希连接)和OPTION(合并连接),但最终出现错误:

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


是否有可能优化此查询?

如果不想联接每一行,可以使用内部联接或左联接。内部联接只返回匹配的行,而左联接也返回左表的空行。右连接也会返回右表的空行。

请详细说明原因? 根据我的经验,您提到的查询不是一个常见的查询,它将导致昂贵的查询计划。如果我们要更好地理解查询的上下文,我们可能会采取不同的方法来提高性能,可能会查询一个存储过程,该存储过程执行多个步骤来检索相关数据,但在每个阶段都以有效的方式执行


一个很好的例子(使用您的场景)是创建一个过程,将相关ID隔离到临时表,然后将其连接(使用“=”而不是“”)以获得结果。

生成包含1690000行的整个笛卡尔积需要多长时间

如果这是合理的时间量,那么考虑使用减法运算符来消除主键匹配的行。差不多

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

整个笛卡尔积很可能需要很长时间才能产生。你为什么需要这样的结果呢?也许有更好的方法来为数据建模。

你知道会有多少结果会返回吗?(如果我没有弄错的话,那就是169万行。)最明显的优化是:不要选择太多东西。@delnan,有一个where子句,我相信它只会是1687400:-)。为什么要做笛卡尔积?对于你的问题,可能有更好的解决办法。@Ben我最初解释了这一点,但大多数舍入方法的结果都是一样的;)我想在T_Car表中找到类似的行。所以我需要比较一行和其他行。当你说相似时,我猜你是说希望比较表中的其他列?是这样吗?@user927524请定义“相似”-这里没有其他人知道你的意思。此查询的主要目的是查找所有重复项。例如,当发动机号相同时,两辆车是重复的,但当产品、型号、颜色、生产日期相同时,也可以重复。我给出的条件是许多条件中的两个。因此,我必须将每一行与其他行的其余部分进行比较。@user927524我想我现在理解得更好了,但还有一个问题。假设您有一个重复的记录,所有列都是重复的(除了标识),还是只有引擎号是重复的,而其他列在两行之间是不同的?请注意,如果我没有弄错的话,SQL Server使用的是“除”而不是“减”(来自Oracle)。