相关疑难解决方法(0)

MERGE 目标表的一个子集

我正在尝试使用MERGE语句从表中插入或删除行,但我只想对这些行的一个子集进行操作。的文档MERGE有一个措辞非常强烈的警告:

仅指定目标表中用于匹配目的的列很重要。也就是说,指定目标表中与源表的相应列进行比较的列。不要试图通过在 ON 子句中过滤掉目标表中的行来提高查询性能,例如通过指定 AND NOT target_table.column_x = value。这样做可能会返回意外和不正确的结果。

但这正是我必须做的事情才能完成我的MERGE工作。

我拥有的数据是一个标准的项目到类别的多对多连接表(例如,哪些项目包含在哪些类别中),如下所示:

CategoryId   ItemId
==========   ======
1            1
1            2
1            3
2            1
2            3
3            5
3            6
4            5
Run Code Online (Sandbox Code Playgroud)

我需要做的是用新的项目列表有效地替换特定类别中的所有行。我最初的尝试是这样的:

MERGE INTO CategoryItem AS TARGET
USING (
  SELECT ItemId FROM SomeExternalDataSource WHERE CategoryId = 2
) AS SOURCE
ON SOURCE.ItemId = TARGET.ItemId AND TARGET.CategoryId = 2
WHEN NOT MATCHED BY TARGET THEN
    INSERT ( CategoryId, ItemId )
    VALUES ( 2, ItemId ) …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql merge

74
推荐指数
1
解决办法
8万
查看次数

我可以优化这个 MERGE 语句吗?

我正在尝试在两个表之间进行单列合并。第一个表 ( VisitorSession) 有 40,000,000 行。第二个 ( ShoppingCart) 有 9,000,000 行。

在我的开发环境中,查询只需不到 8 分钟。但是在生产环境中,它应该占用更少(更强大的机器)。但是,我预计该查询至少需要 2 分钟才能在生产中运行。我知道这个查询会导致开发环境中的其他开发人员超时,这意味着它很容易导致客户超时。是否有更安全和/或更快的方法来执行此查询?

declare @dt datetime = cast(dateadd(month, -6, getdate()) as date);

merge ShoppingCart as TargetTable  -- 07:55 to complete in Dev
using 
(
  select * from -- 04:55 to run select, resulting in 12,727,927 rows in Dev
  (
    select
      visitorid  -- int, not null, foreign key
      ,useripaddress  -- varchar(55), null
      ,row_number() over 
      (partition by visitorid order by createdate desc) as [row]
    from VisitorSession (nolock) …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization merge

6
推荐指数
1
解决办法
8298
查看次数

标签 统计

merge ×2

sql-server ×2

optimization ×1

t-sql ×1