需要一些帮助来理解UPDATE以下语句之一的缓慢:-
UPDATE TOP (100) xyz
SET xyz.flag = 1
OUTPUT inserted.Rcode, inserted.EDR, inserted.id, abc.EID,abc.CID,abc.ENID,abc.Cdate
FROM dbo.table1 xyz WITH (UPDLOCK, READPAST)
INNER JOIN dbo.table2 abc WITH (NOLOCK)
on xyz.id=abc.id
WHERE xyz.flag = 0
Run Code Online (Sandbox Code Playgroud)
表1有大约。50 万行,表 2 大约有。500 万行
哈希匹配不同流运算符显示黄色警报,消息为:
操作员使用 Tempdb 溢出数据,以溢出级别 4 和 1 个溢出线程执行”
构建残差:
database.dbo.table2.id as abc.id = database.dbo.table2.id as abc.id
我截了屏。不幸的是,由于安全原因,我不能提供更多,甚至不能提供匿名计划。从我的工作站我无法访问互联网,所以我无法让计划浏览器在那里运行。
通常,对于较小的行子集,它在几秒钟内,就像我们刚刚匹配 10K 行或其他东西一样。但是随着数据量的增加,这似乎是一个临界点,应用程序无法承受 1 分钟的运行时间。从 SSMS 我得到 30 秒,但从应用程序我们有平均。约 50 秒 RCSI 处于测试阶段。
我的好计划没有显示 Hash Match Flow Distinct 运算符,如我的屏幕截图所示,而其余计划保持不变。好的一个在 3 秒左右完成。正如所见,该操作员花费了近 16 秒。我们可以通过适当的索引或查询重写来消除它吗? …
sql-server execution-plan update sql-server-2014 query-performance
我们支持基于 SQL Server 的内部应用程序的多种部署。
我们现在遇到过几次问题,一些曾经快速而小的查询突然变得非常缓慢或不稳定,而不一定会产生更多的数据或在更大的数据集上运行。
每次发生这种情况时,都是突然开始缓慢运行的不同查询。每当这种情况发生时,我们必须花一些开发时间来调试问题,可能会再次编写查询并与以前的版本进行基准测试等等。 然而,原始查询通常可以正常工作多年,而且我们事先没有迹象表明它的执行时间可能会爆炸。
有哪些好的做法可以防止查询随机变慢?
我所追求的不是“如何修复我们已经观察到很慢的查询”,而是首先如何降低查询变慢的可能性——一种主动的方法,而不是被动的。我需要一种方法来强制 SQL Server 不要尝试过多地优化查询:我真的不需要快速,我需要一致。如果有一些选择让 SQL Server 在构建查询计划时更加保守,而不是试图利用数据分布等,我会追求它们。
UPDATE MARK M SET ARCHIVE_FLAG = 'N' WHERE EXISTS
(SELECT /*+ cardinality(S1, 10) parallel(S1,8)*/ 1 FROM SHFASG S, SHIFT S1
WHERE S.ID = S1.ID AND M.ID = S.MARKID AND ARCHIVE_FLAG <> 'Y');
Run Code Online (Sandbox Code Playgroud)
这是我拥有的 oracle 查询,我想为我的 MS SQL DB 创建类似的查询,请提供任何帮助
sql-server optimization parallelism cardinality-estimates query-performance
多年来,一直有一个长时间运行的 SQL 代理作业需要近两个小时才能完成。大约两周前,出于一个小小的突发奇想,决定改变相关数据库的增长率。此后,这项工作在不到 30 分钟的时间内就完成了。改变日志的增长率会强制生成新的执行计划。我只是好奇 SQL Server 内部发生了什么,这会导致更快的运行时间。
谢谢
SELECT x, y, z,
CASE
WHEN COUNT (PH.header_id) OVER (PARTITION BY PL.header_id)
NOT IN (null,0) THEN L_Count
ELSE COUNT (PH.header_id) OVER (PARTITION BY PL.header_id)
END as quantity
Run Code Online (Sandbox Code Playgroud)
有没有更有效的写法?
我非常清楚它在一张大桌子上执行了两次计数。
不幸的是,我无法发布查询计划,因为我正在使用的用户帐户正在等待 SHOWPLAN 权限。
NOT IN 子句是一个附带问题。感谢您提供有关改进方法的评论反馈,但问题的焦点是重复计数。
根据我的经验,如果您的数据库中有数千/数百万行,如本答案以及我在这里回答的内容和提问者的回答SELECT TOP中所示,则要快得多。SELECT MIN()MAX()
我的问题是为什么,根据我的理解,TOP查看数据SELECT column FROM table与执行 a 时相同ORDER BY column,它会对结果进行排序,然后只给出顶行,而MIN()/MAX()函数实际上应该只查看每一行,检查该行的总和行,然后转到下一行,如果该行是>或<前一行,则将结果保存在函数中取决于它是否为 saMAX()或 a MIN(),而这正是ORDER BY应该做的。
请不要回答,根据您的经验, 比MAX()更好TOP,因为问题实际上是MAX()/MIN()和之间有什么区别TOP?两者都查看每一行的数据,并且都可能是log(n)。
回复@JD:
\n\n\n一个简单的例子是,如果您使用 TOP 而不使用 ORDER BY 子句。然后,您将返回的最高结果可能是不确定的,并且并不总是必须与 MAX() 聚合函数引用的同一行。
\n
当然,我只是问你何时使用,ORDER BY …
我有这张表,有 3 条记录。3条记录是创建脚本。我需要执行创建脚本,如果发生208错误,那么我需要保留记录并将状态设置为1。然后在其他记录完成后再次执行它。如果没有错误或者有除 208 之外的任何其他错误,我需要从表中删除它。但是当我执行它时,它会无限循环。我该如何解决?
问题是第二个视图参考了第一个视图。所以我需要先创建第二个,然后创建第一个。这就是我创建这个 SP 的原因。任何其他想法也表示赞赏。我是编码新手,所以请原谅我犯的任何错误。
Create PROCEDURE [dbo].[UP_CREATE_SCRIPT]
AS
BEGIN
declare @qry1 nvarchar(max)
DECLARE @i INT =1
DECLARE @qry2 NVARCHAR(100)
IF EXISTS (select 1 from [SmartMigrateDB_New].dbo.temp3 where id>0 and type<>'sq')
BEGIN
truncate table error_log
while (select count(1) from [SmartMigrateDB_New].dbo.temp3 where status=1)>=0
BEGIN
WHILE @i <= (SELECT MAX(ID) FROM [SmartMigrateDB_New].dbo.temp3)
BEGIN
BEGIN TRY
set @qry1 = ( select code from [SmartMigrateDB_New].dbo.temp3 where id = @i )
print @qry1
EXEC sp_ExecuteSQL @qry1
update [SmartMigrateDB_New].dbo.temp3 set status=0 where id = …Run Code Online (Sandbox Code Playgroud) sql-server stored-procedures functions errors query-performance
比较查询性能时应该检查哪些因素?
我看到很多关于 IO 成本、子树成本(通过使用执行计划)、CPU 时间、运行时间(通过使用 set statistics time on)、运行查询所需的时间等统计信息的文章。
我见过一些具有高子树成本但执行速度快的查询。所以我想知道在检查查询性能时我必须考虑哪些因素。
使用 Demo from here重现我的问题,更改表结构如下,并将演示分区函数修改为 datetime
CREATE TABLE [dbo].[DemoPartitionedTable](
[DemoID] [int] IDENTITY(1,1) NOT NULL,
[SomeData] [sysname] NOT NULL,
[CaptureDate] [datetime] NULL,
CONSTRAINT [PK_DemoPartitionedTable] UNIQUE NONCLUSTERED
(
[DemoID] ASC,
[CaptureDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
Run Code Online (Sandbox Code Playgroud)
用户运行如下查询(查询 1)
SELECT [DemoID], [SomeData], [CaptureDate] FROM
[dbo].[DemoPartitionedTable] WHERE (1=1) and (1=1) and
CONVERT(varchar(10),CaptureDate,112) between 20190912 and 20190912
Run Code Online (Sandbox Code Playgroud)
计划是https://www.brentozar.com/pastetheplan/?id=r1veZhovH
大约需要 4 小时才能返回 500 万行
如果我使用如下分区键来改进上面的代码(查询 2)
SELECT [DemoID], [SomeData], [CaptureDate] FROM …Run Code Online (Sandbox Code Playgroud) performance sql-server partitioning sql-server-2012 query-performance performance-tuning
我使用的是 SQL Server 2008 及以上版本。
我有以下两个表:
MasterTable
MId
DetailsCount DEFAULT 0
DetailsTable
DId
MId
Run Code Online (Sandbox Code Playgroud)
在 中,我将匹配的MasterTable.DetailsCount记录数存储在 中。DetailsTableMId
首先将记录插入到主表中,然后将给定 MId 的数千条记录插入到详细信息表中。这发生在多个线程上。每个线程都有自己的SqlConnection.
详细信息表中的总记录数为数百万,并且还在不断增加。
在DetailsTable.MId列上添加非聚集索引。无法添加聚集索引。
我尝试过两种维护DetailsCount专栏的方法:
DetailsCount使用查询:UPDATE MasterTable
SET DetailsCount = (SELECT COUNT(*) FROM DetailsTable WHERE MId = ?)
WHERE MId = ?
Run Code Online (Sandbox Code Playgroud)
由于详细信息表中有数百万条记录,这种方法的性能不高,因为每次在其中添加新记录时我都需要扫描详细信息表(以获取计数)。即使使用非聚集索引,它的性能也不佳。如果我们简单地评论该列的更新,我们会看到性能的显着提高。
DetailsCountusing 查询:UPDATE MasterTable
SET DetailsCount = DetailsCount + 1
WHERE MId = ?
Run Code Online (Sandbox Code Playgroud)
这种方式更好,因为我不需要访问详细信息表。
但是,详细信息表中的插入发生在多个线程上。每个线程使用不同的SqlConnection实例。
这就是为什么DetailsCount经常会更新错误的值。
我查看了 …
sql-server ×10
performance ×2
update ×2
aggregate ×1
case ×1
count ×1
errors ×1
filegroups ×1
functions ×1
optimization ×1
parallelism ×1
partitioning ×1