小编Mar*_*ith的帖子

SQL Server 中的 B 树节点拆分策略用于单调递增值

考虑一个总是单调增加的值的 B 树索引,例如 IDENTITY 类型的列。使用传统的 B 树实现,每当节点已满时,它将被拆分 50%/50%,我们最终得到一个 B 树,其中(几乎)所有节点都只有 50% 已满。

我知道 Oracle 会发现值何时不断增加,在这些情况下,Oracle 会执行 90%/10% 的拆分。这样,(几乎)所有节点都将充满 90%,并且对于这些非常常见的情况,可以获得更好的页面利用率。

我无法在 SQL Server 中找到类似功能的文档。但是,我进行了两次实验,分别在索引中插入了 N 个随机整数和 N 个连续整数。前一种情况使用了更多的页面,后者。

SQL Server 是否提供类似的功能?如果是这样:你能指点我一些关于这个功能的文档吗?

更新: 通过下面提供的实验,似乎叶节点保持未分裂,内部节点分裂 50%/50%。这使得增加键上的 B 树比随机键上的更紧凑。然而,Oracle 的 90%/10% 方法甚至更好,我仍然在寻找一些官方文档来验证实验中看到的行为。

index sql-server fragmentation page-splits

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

“常量表” - 这是常见的做法吗?

大学 SQL 课程,使用 John J. Patrick 所著的“SQL Fundamentals”一书。在第三章中,他谈到使用“常量表”向 select 语句添加列,其中所有行都具有相同的值。

例如,如果您有表“字符”,如下所示:

first_name  last_name  dept_code
----------- ---------- -------------------
Fred        Flintstone ROCKS
Barney      Rubble     ROCKS
Wilma       Flintstone FACEPALMING_AT_FRED
Run Code Online (Sandbox Code Playgroud)

并且您想要一个 SELECT 向所有行添加值为“BEDROCK”的列“hometown”,他建议在数据库中创建第二个表“temp”,

hometown
--------
BEDROCK
Run Code Online (Sandbox Code Playgroud)

然后做

SELECT first_name, last_name, dept_code, hometown FROM characters, temp
Run Code Online (Sandbox Code Playgroud)

这个想法是避免将字符串常量放在 SELECT 语句中,并且如果您有很多需要相同常量的 SELECT,更新一个表比更新 50 个查询更容易。

问题是,过去 15 年来我一直在使用 SQL 数据库,但我从未见过这种结构。它是我刚刚错过的完全常见的东西,还是在这个任务结束后我可以从我的记忆中抹去的东西?

best-practices

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

如何避免在存储过程中使用的 sql 查询中使用 IN 子句

除了在下面给定的 SP 中使用 IN 子句之外,还有没有更好的方法来编写 SQL。当我使用这个 IN 子句时,由于 User 和 Member 表中涉及大量或记录,我的性能下降。

CREATE PROCEDURE [dbo].[sp_MemberIdsFromUserIds] @dtUserIds UNIQUETABLE readonly
AS
  BEGIN
      SELECT userID,
             Memberid
      FROM   Member
             INNER JOIN USER
               ON UserMemberID = MemberiD
      WHERE  userID IN (SELECT UniqueId
                        FROM   @dtUserIds)
  END 
Run Code Online (Sandbox Code Playgroud)

请提出替代方案,因为我对写作 SP 没有完整的了解

sql-server stored-procedures

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

重建完成后重建索引会导致性能下降吗?

我们有一个严重碎片化的客户数据库——实际上每个超过 1000 页的表都有 >95% 的碎片。填充因子设置为合理的值,但页面空间使用量远不及大多数表的填充因子。

这是没有对数据库执行维护的结果。

使用Ola Hallengren 的 IndexOptimize重建索引可按预期减少碎片。在现有的生产硬件上,应用程序的性能按预期提高。我通常使用的所有指标——大量查询的客户端统计、分析器持续时间、读/写停顿、应用程序日志和用户感知——都表明性能得到了提高。

然而,支持英特尔 PCIe SSD 的新数据库服务器显示出与我们预期相反的情况。高度分散,应用程序运行良好。重建索引后,应用程序性能不佳。一些需要约 90 秒的操作现在需要约 6 分钟。但是,其他指标似乎都没有表明系统运行速度变慢。

这是其他人经历过的吗?

index sql-server optimization fragmentation

8
推荐指数
2
解决办法
6551
查看次数

GROUPING SETS 使用计算表达式返回意外结果

这里我们有两个类似的查询,使用grouping sets whereSELECT子句包含一些在聚合中计算的表达式:

SELECT RN10, RN10 / 10, COUNT(*) FROM 
(
       SELECT RN, RN/10 AS RN10, RN/100 AS RN100 FROM 
       (
               SELECT RN = -1 + ROW_NUMBER() OVER (ORDER BY 1/0) 
               FROM master..spt_values
       ) A
) B
GROUP BY GROUPING SETS ((RN10), (RN10 / 10), ())
ORDER BY 1, 2
Run Code Online (Sandbox Code Playgroud)

它的计划在这里:第一个查询计划

SELECT RN10, SUBSTRING(RN,3,99), COUNT(*) FROM 
(
       SELECT RN, SUBSTRING(RN,2,99) AS RN10 FROM 
       (
               SELECT RN = CAST(-1 + ROW_NUMBER() OVER (ORDER BY 1/0) AS …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan group-by

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

#SP2010 场极慢的 StatMan 查询问题

我在为此创建的博客文章中解释了我遇到的问题(易于参考和管理 1 个位置的响应/解决方案),可在此处找到:http : //schoennie.blogspot.com/ 2013/09/slow-statman-query-issue-with-sp2010.html

简短的总结是,在 SQL 2008R2(同一服务器)之上安装 SharePoint 2010 的单个服务器在特定时间间隔内(似乎是每天早上)在每次第一次上传时都遇到非常缓慢的响应。分析 SQL 活动后,我发现当您开始上传时,此查询会在上传的“插入部分”之前执行:

SELECT StatMan([SC0], [LC0])
FROM   (SELECT TOP 100 PERCENT CONVERT(VARBINARY, 
                                        SUBSTRING ([Content], 1, 100) + 
                                        +SUBSTRING([Content], CASE
                                                                WHEN LEN([Content]) <= 200 THEN 101
                                                                ELSE LEN([Content]) - 99
                                                            END, 100)) AS [SC0],
                                        DATALENGTH([Content])   AS [LC0]
        FROM   [dbo].[AllDocStreams] WITH (READUNCOMMITTED)
        ORDER  BY [SC0]) AS _MS_UPDSTATS_TBL 
Run Code Online (Sandbox Code Playgroud)

我现在花了几天时间试图获得有关此 StatMan 查询的更多信息,以及为什么它会导致磁盘 i/o 通过屋顶和磁盘队列长度增长到 5 值以上(通常约为 0.01)

请分享您对此的想法,或者为我指明某个方向/资源?我在这个软件领域作为 SharePoint 顾问和 DBA 参与了大约 8 年,但我还没有见过这样的事情!

非常感谢,杰罗恩

performance statistics sharepoint sql-server-2008-r2

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

哪个 DBMS 更符合标准?

我发现相同的查询在不同的 DBMS 中不起作用令人沮丧。

例如,某些 DBMS(例如 Microsoft SQL Server 和 MySQL)似乎支持该information_schema表,而其他DBMS(例如SQLite)则不支持。

一些数据库如 MySQL 允许你做SHOW TABLES,等等。

有些限制使用结果,SELECT TOP 10 ...而其他限制使用... LIMIT 10.

为什么不同的 DBMS 如此不兼容和异常?

他们为什么不遵循 SQL 标准?

哪些擅长坚持SQL标准?

哪些在遵守 SQL 标准方面是出了名的差?

sql-standard

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

按升序和降序划分

我有一个表,对于一组给定的字段 a、b 和 c,我需要获取按 d 和 e 排序的第一行和最后一行,并且正在使用 ROW_NUMBER 来获取这些行。声明的相关部分是...

ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d ASC, e ASC) AS row_number_start,
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d DESC, e DESC) AS row_number_end
Run Code Online (Sandbox Code Playgroud)

执行计划显示了两个排序操作,每个操作一个。这些排序操作占语句总成本的 60% 以上(我们在这里谈论的是数千万行,分区通常每个分区有 1-100 条记录,大部分在 10 条以下)

所以如果我能摆脱其中的一个就好了。我试图创建一个索引来复制排序;这消除了排序操作之一,但没有消除后者。(请注意,创建的任何索引仅用于此过程,并且会作为 ETL 过程的一部分每天重新创建。)

从检查执行计划来看,我认为问题是在执行partition by语句时,SQL Server坚持按分区列升序排序。从逻辑上讲,是升序还是降序都没有关系,如果优化器理解这一点,那么它可以向后读取相同的索引来计算 row_number_end。

有什么方法可以让优化器在这里看到意义,或者有人可以建议另一种方法来实现相同的最终目标吗?

sql-server sql-server-2012 greatest-n-per-group

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

为什么 SQL Server 估计在插入一些行后从连接中会发出更少的行?

下面是我在生产中遇到的事情的简化版本(在处理异常大量批次的一天,计划变得灾难性地更糟)。

已使用新的基数估计器针对 2014 年和 2016 年对 repro 进行了测试。

CREATE TABLE T1 (FromDate  DATE, ToDate DATE, SomeId INT, BatchNumber INT);

INSERT INTO T1
SELECT TOP 1000 FromDate = '2017-01-01',
                ToDate = '2017-01-01',
                SomeId = ROW_NUMBER() OVER (ORDER BY @@SPID) -1,
                BatchNumber = 1
FROM   master..spt_values v1

CREATE TABLE T2 (SomeDateTime DATETIME, SomeId INT, INDEX IX(SomeDateTime));

INSERT INTO T2
SELECT TOP 1000000 '2017-01-01',
                   ROW_NUMBER() OVER (ORDER BY @@SPID) %1000
FROM   master..spt_values v1,
       master..spt_values v2
Run Code Online (Sandbox Code Playgroud)

T1 包含 1,000 行。

FromDateToDate …

sql-server sql-server-2014 cardinality-estimates

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

Blocking_session_id 怎么可能是负 2?

我有一个案例,我正在运行的查询需要很长时间。当我检查sys.dm_exec_requestsblocking_session_id是一个负值时,具体来说是-2。等待是一个LCK_M_X,阻塞的命令是一个DELETE语句。据我所知,目前没有其他东西触及那张桌子。事实上,唯一的活动请求是被阻止的连接和查询检查sys.dm_exec_requests。当我查看sys.dm_tran_session_transactions被阻止的会话时,只有一个出现。

sql-server-2008 sql-server blocking

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