标签: sql-server

高效插入带有聚集索引的表

我有一个 SQL 语句,该语句将行插入到表中,并且在 TRACKING_NUMBER 列上具有聚集索引。

例如:

INSERT INTO TABL_NAME (TRACKING_NUMBER, COLB, COLC) 
SELECT TRACKING_NUMBER, COL_B, COL_C 
FROM STAGING_TABLE
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 在聚集索引列的 SELECT 语句中使用 ORDER BY 子句是否有帮助,或者是否会因 ORDER BY 子句所需的额外排序而否定任何获得的收益?

performance sql-server clustered-index insert

31
推荐指数
3
解决办法
7万
查看次数

使用 SQL Server 进行负载平衡

当今存在的在 Windows Server 上执行 Microsoft SQL Server 负载平衡并对任何编程访问透明的方法。这是内置的还是必须购买解决方案?

我试图找出今天是否有一个解决方案,从 Web 服务器或其他数据库访问 SQL Server 的角度来看,它使这变得非常容易。

sql-server

31
推荐指数
2
解决办法
7万
查看次数

为什么索引 REBUILD 不会减少索引碎片?

我已经使用 ALTER INDEX REBUILD 来删除索引碎片。在某些情况下,REBUILD 似乎并没有消除这种碎片。REBUILD 不去除碎片的原因是什么?似乎这种情况尤其发生在小索引上。

index sql-server clustered-index fragmentation

31
推荐指数
2
解决办法
4万
查看次数

为什么 GROUP BY 语句中的通配符不起作用?

我正在尝试使以下 SQL 语句起作用,但出现语法错误:

SELECT A.*, COUNT(B.foo)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.PKey = B.FKey
GROUP BY A.*
Run Code Online (Sandbox Code Playgroud)

这里,A 是一个有 40 列的宽表,如果可能,我想避免在 GROUP BY 子句中列出每个列名。我有很多这样的表,我必须在这些表上运行类似的查询,所以我必须编写一个存储过程。解决这个问题的最佳方法是什么?

我正在使用 MS SQL Server 2008。

sql-server-2008 sql-server t-sql group-by

31
推荐指数
2
解决办法
2万
查看次数

是否可以将一列设为只读?

我很好奇是否可以创建一个包含永远无法更改的列的表,但该表的其他列可以。

例如,我可以想象一个CreatedByUser永远不应更改的列。

SQL Server 中是否有为此提供内置功能,还是只能通过触发器或其他方式实现?

sql-server

31
推荐指数
2
解决办法
3万
查看次数

为什么执行语句的速度取决于网络连接?

看起来执行 T-SQL 的速度取决于与服务器的网络连接的延迟。我假设如果 SQL Server 没有什么可向客户端报告的,它只会执行直到完成,但测试显示了另一个故事。

create procedure UselessLoop
  @I int
as
declare @D datetime = getdate()
while @I > 0 set @I -= 1
print datediff(millisecond, @D, getdate())
Run Code Online (Sandbox Code Playgroud)

exec UselessLoop 100000

Server    Milliseconds
local     53
nearby    63
faraway   660
Run Code Online (Sandbox Code Playgroud)

exec UselessLoop 1000000

Server    Milliseconds
local     546
nearby    640
faraway   6183
Run Code Online (Sandbox Code Playgroud)

使用 SSMS 对来自不同计算机的同一服务器执行测试。本地从服务器执行,附近在同一个本地网络上,远处是从 500 公里外的另一个办公室执行,通过 1 Gb 光纤连接。

显然,SQL Server 和客户端之间存在一些直接依赖于执行的语句数量的通信。

我使用 Wireshark 查看传输的内容,我不能说我理解那么多,但它是一个 tcp.stream,在 22740 个数据包中交换了总共 26 MB。

一个无用的函数呢?

create function dbo.UDFUselessLoop(@I int)
returns int
as
begin
  declare …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

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

全文索引维护指南

维护全文索引应考虑哪些准则?

我应该重建还是重组全文目录(请参阅BOL)?什么是合理的维护节奏?可以使用哪些启发式方法(类似于 10% 和 30% 碎片阈值)来确定何时需要维护?

(下面的所有内容只是详细说明该问题并显示我到目前为止所想的内容的额外信息。)



额外信息:我的初步研究

有很多关于 b 树索引维护的资源(例如,这个问题、Ola Hallengren 的脚本以及来自其他站点的大量关于该主题的博客文章)。但是,我发现这些资源都没有提供用于维护全文索引的建议或脚本。

有Microsoft 文档提到对基表的 b 树索引进行碎片整理然后在全文目录上执行重组可能会提高性能,但它没有涉及任何更具体的建议。

我也发现了这个问题,但它主要关注更改跟踪(如何将底层表的数据更新传播到全文索引中),而不是可以最大化索引效率的定期维护的类型。

额外信息:基本性能测试

此SQL Fiddle包含的代码可用于创建带有AUTO更改跟踪的全文索引,并在修改表中的数据时检查索引的大小和查询性能。当我在生产数据的副本上运行脚本的逻辑(而不是小提琴中的人工制造数据)时,以下是我在每个数据修改步骤后看到的结果的摘要:

在此处输入图片说明

尽管此脚本中的更新语句相当人为,但这些数据似乎表明定期维护可以获得很多好处。

额外信息:初步想法

我正在考虑创建一个每晚或每周的任务。似乎此任务可以执行 REBUILD 或 REORGANIZE。

因为全文索引可能非常大(数千万或数亿行),所以我希望能够检测目录中的索引何时足够碎片化,从而需要进行 REBUILD/REORGANIZE。我有点不清楚什么启发式可能对此有意义。

sql-server full-text-search index-maintenance

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

什么是 WITH CHECK CHECK 约束?

我有一些自动生成的 T-SQL,这可能是有效的,但我不太明白。

ALTER TABLE [dbo].[MyTable]
WITH CHECK
CHECK CONSTRAINT [My_FORIEGN_KEY];
Run Code Online (Sandbox Code Playgroud)

我知道什么是外键约束,但什么是外键约束CHECK CHECK?

sql-server constraint t-sql

31
推荐指数
1
解决办法
4万
查看次数

使用 SQL CLR 标量函数模拟 HASHBYTES 的可扩展方式是什么?

作为 ETL 过程的一部分,我们将暂存中的行与报告数据库进行比较,以确定自上次加载数据以来是否有任何列实际发生了更改。

比较基于表的唯一键和所有其他列的某种散列。我们目前使用HASHBYTES该SHA2_256算法,并发现如果许多并发工作线程都在调用HASHBYTES.

在 96 核服务器上进行测试时,以每秒哈希数衡量的吞吐量不会增加超过 16 个并发线程。我通过将并发MAXDOP 8查询的数量从 1更改为12 来进行测试。测试MAXDOP 1显示了相同的可扩展性瓶颈。

作为一种解决方法,我想尝试 SQL CLR 解决方案。这是我试图说明要求的尝试:

  • 该函数必须能够参与并行查询
  • 函数必须是确定性的
  • 该函数必须接受一个NVARCHAR或VARBINARY字符串的输入(所有相关列都连接在一起)
  • 字符串的典型输入大小为 100 - 20000 个字符。20000 不是最大值
  • 哈希冲突的几率应该大致等于或优于 MD5 算法。CHECKSUM对我们不起作用,因为冲突太多。
  • 该函数必须在大型服务器上很好地扩展(每个线程的吞吐量不应随着线程数量的增加而显着降低)

对于 Application Reasons™,假设我无法保存报告表的哈希值。这是一个不支持触发器或计算列的 CCI(还有其他我不想讨论的问题)。

HASHBYTES使用 SQL CLR 函数进行模拟的可扩展方式是什么?我的目标可以表示为在大型服务器上每秒获得尽可能多的哈希值,因此性能也很重要。我对 CLR 很糟糕,所以我不知道如何做到这一点。如果它激励任何人回答,我计划尽快为这个问题添加赏金。下面是一个示例查询,它非常粗略地说明了用例:

DROP TABLE IF EXISTS #CHANGED_IDS;

SELECT stg.ID INTO #CHANGED_IDS
FROM (
    SELECT ID,
    CAST( HASHBYTES ('SHA2_256', 
        CAST(FK1 AS NVARCHAR(19)) + 
        CAST(FK2 AS NVARCHAR(19)) …
Run Code Online (Sandbox Code Playgroud)

sql-server etl sql-clr hashing sql-server-2016

31
推荐指数
4
解决办法
1948
查看次数

添加选择时超出自引用标量函数嵌套级别

目的

在尝试创建自引用函数的测试示例时,一个版本失败而另一个版本成功。

唯一的区别是添加SELECT到函数体导致两者的执行计划不同。


起作用的功能

CREATE FUNCTION dbo.test5(@i int)
RETURNS INT
AS 
BEGIN
RETURN(
SELECT TOP 1
CASE 
WHEN @i = 1 THEN 1
WHEN @i = 2 THEN 2
WHEN @i = 3 THEN  dbo.test5(1) + dbo.test5(2)
END
)
END;
Run Code Online (Sandbox Code Playgroud)

调用函数

SELECT dbo.test5(3);
Run Code Online (Sandbox Code Playgroud)

退货

(No column name)
3
Run Code Online (Sandbox Code Playgroud)

不起作用的功能

CREATE FUNCTION dbo.test6(@i int)
RETURNS INT
AS 
BEGIN
RETURN(
SELECT TOP 1
CASE 
WHEN @i = 1 THEN 1
WHEN @i = 2 THEN 2
WHEN @i = 3 …
Run Code Online (Sandbox Code Playgroud)

sql-server functions sql-server-2017

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