标签: sql-server

列存储索引的结构是什么?

SQL Server 2012 中代号DenaliColumnstore 索引的新功能之一

我对常规的旧行存储索引非常了解,例如 b 树结构、叶级和 b 树页面之间的存储差异、包含字段的影响、优化使用它们、键的顺序等。

我很难获得有关列存储索引内部结构的任何好的信息。

  • 它的结构如何?
  • 有b树吗?有其他结构吗?
  • 数据是如何组织的?
  • 什么样的特定运算符最适合使用它?
  • 使用它们时要避免的任何其他反模式?

我能找到的很多关于它们的信息基本上与“正常”索引完全相反,即没有键的排序,没有包含的字段,只有非聚集。

任何见解表示赞赏。

index sql-server sql-server-2012 columnstore

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

关于诊断“有时”慢查询的建议

我有一个存储过程,它通过覆盖索引从索引视图返回结果。通常,它运行得很快(~10 毫秒),有时它可以运行长达 8 秒。

这是一个随机执行示例(注意:这不是一个缓慢的执行,但是除了传递的值之外,查询文本是相同的):

declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)

exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2
Run Code Online (Sandbox Code Playgroud)

这是 SPROC:

ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
    @LocationIds IdentityType READONLY,
    @StatusType TINYINT
AS
BEGIN
    SET NOCOUNT ON;

    SELECT      -- lots of fields
    FROM        [dbo].[ListingSearchView][a] WITH (NOEXPAND)
    INNER JOIN  @LocationIds [b] ON [a].[LocationId] = [b].[Id]
    WHERE       [a].[StatusType] = @statusType
    OPTION (RECOMPILE);
Run Code Online (Sandbox Code Playgroud)

(注意:我OPTION (RECOMPILE) …

performance sql-server sql-server-2012 azure-vm query-performance

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

为什么我的 STRING_AGG 中的 ORDER BY 并不总是有效?

我有一个表,其中包含记录 ID、组 ID(将 1 个或多个记录链接到一个组中)以及每个记录的哈希值。

CREATE TABLE HashTable(
    RecordID VARCHAR(255),
    GroupIdentifier VARCHAR(255),
    Hash VARCHAR (255),
    GroupHashList VARCHAR(4000)
)
Run Code Online (Sandbox Code Playgroud)

(我知道这不是一个有效的表,但它只是用于本示例的临时表)。

我想为每个组生成一个哈希值,所以我认为最简单的方法是连接组中每个记录的哈希值。RecordID 是唯一的,但这些记录所涉及的内容不一定是唯一的,因此散列可能是重复的。这样做的目的是标记完全重复的组,即该组中的所有记录都是另一组中的所有记录的重复项的组。如果 GUI 要将组中的所有成员识别为重复组,则需要该组的所有成员具有相同的哈希值。

我使用 STRING_AGG 连接组中记录的各个散列,并按散列对它们进行排序,以确保我为重复的组获得相同的字符串。我实际上并不关心哈希的顺序是什么,只要每次都相同即可。当我将其作为 SELECT 查询运行时,它工作正常,并且我可以看到重复组的相同字符串。当我采用相同的 SELECT 查询并将其放入 UPDATE 查询中时,顺序似乎丢失了。

SELECT STRING_AGG([Hash],';') WITHIN GROUP (ORDER BY [Hash] ASC) 
FROM HashTable
GROUP BY [GroupIdentifier]
Run Code Online (Sandbox Code Playgroud)

这给出了结果(对于一对重复组的示例):

CREATE TABLE HashTable(
    RecordID VARCHAR(255),
    GroupIdentifier VARCHAR(255),
    Hash VARCHAR (255),
    GroupHashList VARCHAR(4000)
)
Run Code Online (Sandbox Code Playgroud)

当我将相同的代码放入 UPDATE 查询中时,它无法正确对它们进行排序:

UPDATE HashTable
SET GroupHashList = c.HashList
FROM HashTable
INNER JOIN (
    SELECT (STRING_AGG([Hash],';') WITHIN GROUP (ORDER BY [Hash] …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql string-aggregation

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

为什么 DELETE 会对性能产生挥之不去的影响?

最后是一个测试脚本,用于比较@table 变量和#temp 表之间的性能。我想我已经正确设置了 - 性能计时是在 DELETE/TRUNCATE 命令之外进行的。我得到的结果如下(以毫秒为单位)。

@Table Variable  #Temp (delete)  #Temp (truncate)
---------------  --------------  ----------------
5723             5180            5506
15636            14746           7800
14506            14300           5583
14030            15460           5386
16706            16186           5360
Run Code Online (Sandbox Code Playgroud)

只是为了确保我是理智的,这表明 CURRENT_TIMESTAMP (aka GetDate()) 是在语句时使用的,而不是批处理时,因此 TRUNCATE/DELETE 与SET @StartTime = CURRENT_TIMESTAMP语句之间不应有交互。

select current_timestamp
waitfor delay '00:00:04'
select current_timestamp

-----------------------
2012-10-21 11:29:20.290

-----------------------
2012-10-21 11:29:24.290
Run Code Online (Sandbox Code Playgroud)

当使用 DELETE 清除表时,第一次运行和后续运行之间的跳转非常一致。我对DELETE 的理解缺少什么?我已经重复了很多次,交换了顺序,调整了 tempdb 的大小以使其不需要增长等。

CREATE TABLE #values (
  id int identity primary key, -- will be clustered …
Run Code Online (Sandbox Code Playgroud)

performance sql-server delete truncate sql-server-2012

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

下载适用于 SQL Server Management Studio 的 SQL Server Profiler

如何分析 SQL Server 2008 数据库以查看正在特定数据库上执行的代码?我记得使用过 SQL Server profiler,但是我在下载 SQL Server 2008 R2 Express 后在 SQL Server Management Studio 中没有看到它。我在哪里可以下载该工具并安装它?我是否需要完整版的 SQL Server 2008 才能看到此选项?

sql-server profiler ssms sql-server-2008-r2 sql-server-express

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

有人使用 SUMA、跟踪标志 8048 或跟踪标志 8015 吗?

最近包含 SQL Server 启动跟踪标志 8048 以解决 SQL Server 2008 R2 系统中严重的自旋锁争用问题。

有兴趣听取其他人的意见,他们发现性能值由跟踪标志 8048(将查询内存授予策略从每个 NUMA 节点提升到每个核心)、跟踪标志 8015(SQL Server 忽略物理 NUMA)或 SUMA(交错足够统一的内存访问,某些 NUMA 机器上的 BIOS 选项)。

跟踪标志 8048

跟踪标志 8015

系统工作负载的详细信息、从出现问题的系统收集的指标以及在干预后从系统收集的指标。

跟踪标志 8048 是一个“修复”,但它是最好的修复吗?SQL Server 是否会因为跟踪标志 8015 而忽略物理 NUMA 已经完成了同样的事情?如何将 BIOS 设置为交错内存,让服务器使用 SMP 模拟 SUMA 行为而不是 NUMA 行为?

关于系统

  • 4 六核 Xeon E7540 @ 2.00GHz,超线程
  • 128 GB 内存
  • WS2008R2
  • MSSQL 2008 R2 SP2
  • 最大值 6

关于工作量

  • 由 2 个报告应用程序服务器驱动的 1000 份批处理计划/排队报告。
  • 3 种口味的批次:每天、每周、每月
  • 与 SQL Server 的所有报表应用程序服务器连接都作为单个服务帐户进行
  • 最大报告并发数 = 90

问题系统的主要发现

  • 从 …

performance sql-server memory sql-server-2008-r2 numa

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

如何选择多列但只能按一分组?

我有一个问题group by,我想选择多列但只按一列分组。下面的查询是我尝试过的,但它给了我一个错误。

SELECT Rls.RoleName,Pro.[FirstName],Pro.[LastName],Count(UR.[RoleId]) as [Count]
from [b.website-sitecore-core].[dbo].[aspnet_UsersInRoles] UR
inner join [b.website-professional-au].[dbo].[Profile]  Pro
on UR.UserId = Pro.Id
inner join [b.website-sitecore-core].[dbo].[aspnet_Roles] Rls
on Rls.RoleId = UR.RoleId
inner join [b.website-professional-au].[dbo].[Gender] Gn
on gn.Id = pro.GenderId
GROUP BY Rls.RoleName;
Run Code Online (Sandbox Code Playgroud)

sql-server group-by

20
推荐指数
1
解决办法
17万
查看次数

聚集列存储索引和外键

我正在使用索引对数据仓库进行性能调整。我对 SQL Server 2014 还是很陌生。Microsoft 描述了以下内容:

“我们将聚集列存储索引视为存储大型数据仓库事实表的标准,并预计它将用于大多数数据仓库场景。由于聚集列存储索引是可更新的,您的工作负载可以执行大量的插入、更新、和删除操作。” http://msdn.microsoft.com/en-us/library/gg492088.aspx

但是,如果您进一步阅读文档,您会发现限制和限制:

“不能有唯一约束、主键约束或外键约束。”

这让我很困惑!出于各种原因(数据完整性、语义层可见的关系......)

所以微软提倡数据仓库场景使用聚集列存储索引;但是,它不能处理外键关系?!

我在这方面正确吗?您会建议哪些其他方法?过去,我在数据仓库场景中使用了非聚集列存储索引,对数据加载进行删除和重建。然而,SQL Server 2014 并没有为数据仓库增加真正的新价值??

foreign-key data-warehouse sql-server columnstore sql-server-2014

20
推荐指数
2
解决办法
5880
查看次数

如何递归地查找行之间经过 90 天的间隔

这是我的 C# homeworld 中的一种微不足道的任务,但我还没有在 SQL 中实现它,并且更愿意基于集合(没有游标)解决它。结果集应该来自这样的查询。

SELECT SomeId, MyDate, 
    dbo.udfLastHitRecursive(param1, param2, MyDate) as 'Qualifying'
FROM T
Run Code Online (Sandbox Code Playgroud)

它应该如何工作

我将这三个参数发送到 UDF 中。
UDF 在内部使用参数从视图中获取相关 <= 90 天之前的行。
UDF 遍历“MyDate”并返回 1(如果它应该包含在总计算中)。
如果不应该,则返回 0。此处称为“合格”。

udf 会做什么

按日期顺序列出行。计算行之间的天数。结果集中的第一行默认为 Hit = 1。如果差异达到 90,则传递到下一行,直到差距总和为 90 天(必须通过第 90 天)到达时,将 Hit 设置为 1 并将差距重置为 0 . 它也可以代替结果中的行。

                                          |(column by udf, which not work yet)
Date              Calc_date     MaxDiff   | Qualifying
2014-01-01 11:00  2014-01-01    0         | 1
2014-01-03 10:00  2014-01-01    2         | 0
2014-01-04 09:30  2014-01-03    1         | 0
2014-04-01 10:00 …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2014 recursive

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

如何防止在列上创建统计信息?

我有一个表,其中有一列我不希望在其上创建或更新统计信息。如果我强制查询优化器使用主键上的统计密度而不是该列上的统计直方图,我会得到更好的连接基数估计。自动更新和自动创建统计信息在数据库级别启用,我无法更改。

如果您想建议防止创建统计信息的替代方法,请记住该表用于被数千个不同查询引用的视图中。我无法控制运行的查询。

我最初的策略是使用NOCOMPUTESAMPLE 0 ROWS选项在列上创建统计信息。我的印象是 SQL Server 不会在已经有统计对象的列上自动创建统计信息,但这已经发生在我们的开发和 QA 服务器上。

创建了新的统计信息COL_GROUP。我的NORECOMPUTE统计数据没有更新。我不知道为什么要创建统计信息,而且我自己也无法通过运行查询来触发它。

有没有办法阻止 SQL Server 自动为一列创建统计信息?我的表只有两列,因此防止在单个表上创建自动统计的解决方案也可以解决我的问题。

跟踪标志 4139 和 2371 处于打开状态,以防有所不同。

如果你想玩转表结构,我已经包含了它和下面的示例数据:

CREATE TABLE X_NO_COLUMN_STATS(
    [COL_USER] [varchar](256) NOT NULL,
    [COL_GROUP] [int] NOT NULL,
 CONSTRAINT [PK_X_NO_COLUMN_STATS] PRIMARY KEY CLUSTERED 
(
    [COL_USER] ASC,
    [COL_GROUP] ASC
)WITH (DATA_COMPRESSION = PAGE)
);

-- prevent stats from being updated on COL_GROUP
CREATE STATISTICS [X_NO_COLUMN_STATS__COL_GROUP] ON X_NO_COLUMN_STATS ([COL_GROUP]) WITH NORECOMPUTE, SAMPLE 0 ROWS;

BEGIN TRANSACTION;
INSERT INTO X_NO_COLUMN_STATS VALUES …
Run Code Online (Sandbox Code Playgroud)

sql-server statistics

20
推荐指数
2
解决办法
1080
查看次数