AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 283805
Accepted
Newbie-DBA
Newbie-DBA
Asked: 2021-01-23 12:51:51 +0800 CST2021-01-23 12:51:51 +0800 CST 2021-01-23 12:51:51 +0800 CST

帮助调整此更新查询或可能的重写

  • 772

我有以下 SQL 查询,它在 avg 上运行。40 秒,需要一些指导,我可以在哪里改进或重写:

   Declare @status_D INT,
      Declare @StatusIP INT,
      Declare @Status_F INT,
    
    SELECT @status_D = Id From Batchtablestatus (NOLOCK) Where desc ='Value1';
    SELECT @StatusIP = Id From Batchtablestatus (NOLOCK) Where desc ='Value2';
    SELECT @Status_F = Id From Batchtablestatus (NOLOCK) Where desc ='Value3'

BEGIN TRAN

 UPdate U
        SET 
         U.[id]= @StatusIP,
         U.[EnabledDate]= Getdate()
         OUTPUT deleted.col1,
         deleted.col2,
         deleted.col3,
         deleted.col4,
         Inserted.id

FROM (

SELECT TOP 5000 * FROM BatchChangeTable WITH (ROWLOCK,UPDLOCK)
WHERE [id] IN ( @status_D ,Status_F)
ORDER BY [ModifiedTime] )U;

  COMMIT TRAN 

我收到来自 blitzcache 的警告,因为强制序列化、昂贵的排序、不可分割和合并加入 "Mant to Many" = True

我们唯一的索引是在 id 上,它是一个以 id 作为前导键列的 NC 索引。

如果可以的话,我会尝试更新我的问题,如果执行计划。截至目前,SELECT 中的表约为 1 亿。在 col1 上也有 PK/CI。

我已经问过用户为什么我们在那个拉近 50 多列但在更新中使用较少的 TOP 中做 *,可能 bi 想错了,但我想到了。

将索引添加到修改时间似乎也无济于事。

请建议还有什么可以检查的。谢谢

计划-索引搜索发生在 NC 索引 id 上 在此处输入图像描述

sql-server query-performance
  • 2 2 个回答
  • 127 Views

2 个回答

  • Voted
  1. Best Answer
    Erik Darling
    2021-01-24T07:18:04+08:002021-01-24T07:18:04+08:00

    警告

    • 强制序列化是因为OUTPUT(没有目标或@table变量会导致这种情况,但不是#temp表)
    • 昂贵的排序是因为您在ModifiedTime没有支持索引和查询模式的情况下进行排序
    • 非 SARGable 警告是因为(如果我记得我是如何正确编写检查的)局部变量。

    如何修复它

    您需要一个良好的支持索引:

    CREATE INDEX super_awesome
    ON dbo.BatchChangeTable
        (id, ModifiedTime)
    INCLUDE
        (EnabledDate);
    

    但是查询的编写方式IN将被解释为范围谓词,并且ORDER BY ModifiedDate可能仍会导致排序操作。为了充分利用索引,您需要更改表单以使用两个相等谓词和 a 。UNION ALL

    您还需要重写查询以使用动态 SQL,以免受到局部变量的副作用的影响。

    成品将如下所示:

    BEGIN TRAN;
    
    /*I'm guessing here, address local factors*/
    CREATE TABLE #output(col1 int, col2 int, col3 int, col4 int, id int)
    
    /*Use parameterized dynamic SQL*/
    DECLARE @sql nvarchar(MAX) = N''
    
    /*Hello I am your friend*/
    SET @sql += N'
    UPDATE u
    SET
        u.id = @StatusIP,
        u.EnabledDate = GETDATE()
    OUTPUT
        deleted.col1,
        deleted.col2,
        deleted.col3,
        deleted.col4,
        Inserted.id
    INTO #output 
    FROM
    (
        SELECT TOP (5000)
            b.*
        FROM 
        (
             SELECT 
                 b2.*
             FROM BatchChangeTable AS b2 WITH (ROWLOCK, UPDLOCK)
             WHERE b2.id = @status_D
             
             UNION ALL 
             
             SELECT 
                 b2.*
             FROM BatchChangeTable AS b2 WITH (ROWLOCK, UPDLOCK)
             WHERE b2.id = @Status_F
             ORDER BY b2.ModifiedTime
        ) AS b
        ORDER BY b.ModifiedTime
    ) AS u;
    ';
    
    EXEC sp_executesql @sql,
                       N'@status_D int,
                         @StatusIP int,
                         @Status_F int',
                         @status_D,
                         @StatusIP,
                         @Status_F;
    
    SELECT 
        o.*
    FROM #output AS o
    
    COMMIT TRAN;         
    

    您需要稍微调整一下以适应您的实际情况,但它应该让您朝着正确的方向前进。

    • 2
  2. Vladislav Zalesak
    2021-01-23T15:44:17+08:002021-01-23T15:44:17+08:00

    基于可用信息的想法:

    1. 添加非聚集索引(id,ModifiedTime)或(ModifiedTime,id),根据您的信息不确定
    2. 尝试重写更新。

    代码:

    update BatchChangeTable 
            SET 
             U.[id]= @StatusIP,
             U.[EnabledDate]= Getdate()
             OUTPUT deleted.col1,
             deleted.col2,
             deleted.col3,
             deleted.col4,
             Inserted.id
    where col1 in (select top 5000 col1 from BatchChangeTable WITH (ROWLOCK,UPDLOCK)
    WHERE [id] IN ( @status_D ,Status_F)
    ORDER BY [ModifiedTime])
    
    • 1

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve