我有一张这样的表:
CREATE TABLE [dbo].[Table](
[Id] [INT] IDENTITY(1,1) NOT NULL,
[A] [NVARCHAR](150) NULL,
[B] [NVARCHAR](150) NULL,
[C] [NVARCHAR](150) NULL,
[D] [NVARCHAR](150) NULL,
[E] [NVARCHAR](150) NULL,
CONSTRAINT [con] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
并查找要加入此表格的表现。
选项1 - 将所有字符串合并到nvarchar主键中,然后执行:
Source.[A] + Source.[B] + Source.[C] + Source.[D] + Source.[E] = Table.PKString
据我所知,这是不好的做法。
选项2 - 使用:
Source.[A] + Source.[B] + Source.[C] + Source.[D] + Source.[E] = Target.[A] + Target.[B] + Target.[C] + Target.[D] + Target.[E]
选项3 - 使用:
Source.[A] = Target.[A] And
...
Source.[E] = Target.[E]
答案 0 :(得分:5)
您的选项1无效,因为它会将('ab','c')
视为等于('a','bc')
。
此外,您的列可以为空,并且连接null会产生null。
由于可空性,您无法将所有列合并到nvarchar
主键中,即使没有这样,您仍然会面临失败的风险,因为最大长度为1,500字节,远远超过最大索引键列大小。
由于类似的长度原因,使用所有列的复合索引也不起作用。
您可以创建一个计算列,该列使用所有这5个列值作为输入来计算校验和或散列值和索引。
ALTER TABLE [dbo].[Table]
ADD HashValue AS CAST(hashbytes('SHA1', ISNULL([A], '') + ISNULL([B], '')+ ISNULL([C], '')+ ISNULL([D], '')+ ISNULL([E], '')) AS VARBINARY(20));
CREATE INDEX ix
ON [dbo].[Table](HashValue)
INCLUDE ([A], [B], [C], [D], [E])
然后在哈希冲突的情况下,在其他5列的剩余谓词的连接中使用它。
如果您希望NULL
比较相等,则可以使用
SELECT *
FROM [dbo].[Table1] source
JOIN [dbo].[Table2] target
ON source.HashValue = target.HashValue
AND EXISTS(SELECT source.A,
source.B,
source.C,
source.D,
source.E
INTERSECT
SELECT target.A,
target.B,
target.C,
target.D,
target.E)
请注意,上面创建的索引基本上会重现整个表格,因此如果您的查询需要覆盖,则可能需要考虑创建为群集。