Sco*_*ain 6 sql-server best-practices t-sql sql-server-2012 merge
我只是想从“优化 MERGE 语句性能”页面。
我正在使用一个数据仓库,它从许多不同的数据库中获取记录并存储数据。我的仓库数据库中的所有表基本上都遵循相同的模式:
CREATE TABLE Foo (
database_guid UNIQUEIDENTIFIER
,FooPk BIGINT
,Bar NVARCHAR(20)
,Qix NCHAR(10)
,CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED (
database_guid ASC
,FooPk ASC
)
)
GO
CREATE PROCEDURE [iv].[LoadSomeTable]
@databaseGUID UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
MERGE Foo
USING #FooStaging AS Source
ON Foo.FooPk = Source.FooPk AND Foo.database_guid = @databaseGUID
WHEN MATCHED THEN
UPDATE SET Bar = Source.Bar
,Qix = Source.Qix
WHEN NOT MATCHED THEN
INSERT (database_guid, FooPk, Bar, Qix)
VALUES (@databaseGUID, FooPk, Bar, Qix);
END
GO
CREATE TABLE #FooStaging (
FooPk BIGINT
,Bar NVARCHAR(20)
,Qix NCHAR(10)
)
--Data gets loaded in to #FooStaging from a C# call to SqlBulkCopy then calls iv.LoadSomeTable
Run Code Online (Sandbox Code Playgroud)
我现在担心的是我刚刚从那个 MSDN 页面上读到了这个声明
仅在 ON
<merge_search_condition>子句中指定用于确定匹配源表和目标表中数据的条件的搜索条件。也就是说,仅指定目标表中与源表的相应列进行比较的列。不包括与其他值(如常量)的比较。
读完之后我想我的查询错了,我的合并语句应该是
MERGE Foo
USING #FooStaging AS Source
ON Foo.FooPk = Source.FooPk
WHEN MATCHED AND Foo.database_guid = @databaseGUID THEN
UPDATE SET Bar = Source.Bar
,Qix = Source.Qix
WHEN NOT MATCHED THEN
INSERT (database_guid, FooPk, Bar, Qix)
VALUES (@databaseGUID, FooPk, Bar, Qix);
Run Code Online (Sandbox Code Playgroud)
但这对我来说并不“感觉”正确,因为该database_guid字段是主键的一部分,所以它不应该包含在on? 如果我在有它WHEN MATCHED,我上传一个数据库,一个FooPk的1话,我上传第二个数据库与FooPk和不同的@databaseGUID我不知道,如果NOT MATCHED会触发与否(只是测试,事实并非如此)。
哪种方式是使用 MERGE 的正确方法?
| 归档时间: |
|
| 查看次数: |
2135 次 |
| 最近记录: |