相关疑难解决方法(0)

为什么创建一个简单的 CCI 行组最多需要 30 秒?

当我注意到我的一些插入花费的时间比预期的要长时,我正在做一个涉及 CCI 的演示。要重现的表定义:

DROP TABLE IF EXISTS dbo.STG_1048576;
CREATE TABLE dbo.STG_1048576 (ID BIGINT NOT NULL);
INSERT INTO dbo.STG_1048576
SELECT TOP (1048576) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

DROP TABLE IF EXISTS dbo.CCI_BIGINT;
CREATE TABLE dbo.CCI_BIGINT (ID BIGINT NOT NULL, INDEX CCI CLUSTERED COLUMNSTORE);
Run Code Online (Sandbox Code Playgroud)

对于测试,我将从临时表中插入所有 1048576 行。只要它没有因某种原因被修剪,这就足以填充一个压缩的行组。

如果我插入所有整数 mod 17000,它需要不到一秒钟的时间:

TRUNCATE TABLE dbo.CCI_BIGINT;

INSERT INTO dbo.CCI_BIGINT WITH (TABLOCK)
SELECT ID % 17000
FROM dbo.STG_1048576
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)

SQL Server 执行时间:CPU 时间 = 359 …

sql-server columnstore sql-server-2016

20
推荐指数
3
解决办法
669
查看次数

为什么 NOLOCK 使带有变量赋值的扫描变慢?

在我目前的环境中,我正在与 NOLOCK 作斗争。我听到的一个论点是锁定的开销会减慢查询速度。所以,我设计了一个测试来看看这个开销可能有多少。

我发现 NOLOCK 实际上减慢了我的扫描速度。

起初我很高兴,但现在我很困惑。我的测试以某种方式无效吗?NOLOCK 实际上不应该允许稍微快一点的扫描吗?这里发生了什么事?

这是我的脚本:

USE TestDB
GO

--Create a five-million row table
DROP TABLE IF EXISTS dbo.JustAnotherTable
GO

CREATE TABLE dbo.JustAnotherTable (
ID INT IDENTITY PRIMARY KEY,
notID CHAR(5) NOT NULL )

INSERT dbo.JustAnotherTable
SELECT TOP 5000000 'datas'
FROM sys.all_objects a1
CROSS JOIN sys.all_objects a2
CROSS JOIN sys.all_objects a3

/********************************************/
-----Testing. Run each multiple times--------
/********************************************/
--How fast is a plain select? (I get about 587ms)
DECLARE @trash CHAR(5), @dt DATETIME = SYSDATETIME()

SELECT @trash …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2016

14
推荐指数
1
解决办法
422
查看次数

EXCEPT 运算符背后的算法是什么?

在 SQL Server 中,Except运算符如何在幕后工作的内部算法是什么?它是否在内部获取每一行的哈希值并进行比较?

David Lozinksi 进行了一项研究,SQL:在不存在新记录的地方插入新记录的最快方法他表明,对于大量行,Except 语句是最快的;与我们下面的结果密切相关。

假设:我认为 Left join 会最快,因为它只比较 1 列,Except 花费的时间最长,因为它必须比较所有列。
有了这些结果,现在我们的想法是,Except 自动并在内部获取每一行的哈希值?我查看了除非执行计划,它确实使用了一些哈希。

背景:我们的团队正在比较两个堆表。表 A 不在表 B 中的行被插入到表 B 中。

堆表(来自旧文本文件系统)没有主键/guids/标识符。有些表有重复的行,所以我们找到每一行的Hash,并去除重复,并创建主键标识符。

1)首先我们运行一个except语句,排除(哈希列)

select * from TableA
Except
Select * from TableB,
Run Code Online (Sandbox Code Playgroud)

2)然后我们在HashRowId上的两个表之间运行左连接比较

select * 
FROM dbo.TableA A
left join dbo.TableB B
    on A.RowHash =  B.RowHash
where B.Hash is null
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,Except Statement Insert 是最快的。

结果实际上与 David Lozinksi 的测试结果接近

在此处输入图片说明

performance sql-server hashing sql-server-2016 except performance-tuning

10
推荐指数
1
解决办法
747
查看次数

数据固有地排序,就好像它是一个聚集索引

我有下表,其中有 750 万条记录:

CREATE TABLE [dbo].[TestTable](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [TestCol] [nvarchar](50) NOT NULL,
    [TestCol2] [nvarchar](50) NOT NULL,
    [TestCol3] [nvarchar](50) NOT NULL,
    [Anonymised] [tinyint] NOT NULL,
    [Date] [datetime] NOT NULL,
CONSTRAINT [PK_TestTable] 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]
Run Code Online (Sandbox Code Playgroud)

我注意到当日期字段上有非聚集索引时:

CREATE NONCLUSTERED INDEX IX_TestTable_Date ON [dbo].[TestTable] ([Date])
Run Code Online (Sandbox Code Playgroud)

- 我运行以下查询:

UPDATE TestTable 
SET TestCol='*GDPR*', TestCol2='*GDPR*', TestCol3='*GDPR*', Anonymised=1
WHERE [Date] <= …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2017

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

如何诊断 try_parse 非常慢?

我有一个非常大的查询,它的运行速度比我想象的要慢,但是对查询执行计划的深入研究并没有帮助揭示这种缓慢。最终我缩小了范围:try_parse是罪魁祸首!

正常查询:

SELECT CloseDate
FROM MyTable

(4959 row(s) affected)

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 17 ms.
Run Code Online (Sandbox Code Playgroud)

使用 try_parse:

SELECT try_parse(CloseDate as datetime using 'en-us')
FROM MyTable

(4959 row(s) affected)

SQL Server Execution Times:
   CPU time = 719 ms,  elapsed time = 718 ms.
Run Code Online (Sandbox Code Playgroud)

后一种情况下的执行计划看起来很无辜:

在此处输入图片说明

有没有什么方法可以让我以后更容易地发现罪魁祸首?缓慢的实际来源完全隐藏在视线之外。

performance sql-server execution-plan sql-server-2012

3
推荐指数
1
解决办法
394
查看次数

RAM 中的逻辑读取是否出现在等待统计信息中或在哪里?

关于 SQLOS 的执行模型(RUNNING 状态、RUNNABLE 队列、WAITER 列表),当当前正在进行 RAM 中页面的逻辑读取时,任务的状态是什么?

如果是 WAITER 列表,最流行的等待类型是什么?

我可以以某种方式测量此类操作所需的时间吗?

我知道很多逻辑读取会减慢您的查询速度,很多表/索引扫描(已经位于缓冲池中)会减慢您的查询速度 - 我只想知道它们如何出现在统计信息/dmv 中或如何将其与其他数据区分开来“经典”等待类型。

performance sql-server waits performance-tuning

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