Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 连接多个nvarchar列_Sql Server_Tsql - Fatal编程技术网

Sql server 连接多个nvarchar列

Sql server 连接多个nvarchar列,sql-server,tsql,Sql Server,Tsql,我有一张这样的桌子: 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] PRIM

我有一张这样的桌子:

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]

选项1无法正常工作,因为它将
('ab','c')
视为等同于
('a','bc')

此外,您的列可以为null,并且连接null将产生null

由于可空性,您无法将所有列合并到一个
nvarchar
主键中,即使不可空,您仍有失败的风险,因为最大长度为1500字节,远远超过了最大索引键列大小

出于类似的长度原因,使用所有列的复合索引也不起作用

您可以创建一个计算列,该列使用所有这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) 

<> P>注意,上面创建的索引基本上再现了整个表,所以如果您的查询需要覆盖,那么您可能需要考虑创建为群集,

好点马丁。我保证非空值…非常好的答案martin。答案中存在的目的是什么,我可以看到你说避免散列冲突。你能详细说明一下吗