这是从临时表中进行的简单选择,在其主键上加入现有表,两个子选择使用 top 1 引用连接表。
在代码中:
SELECT
TempTable.Col1,
TempTable.Col2,
TempTable.Col3,
JoinedTable.Col1,
JoinedTable.Col2,
(
SELECT TOP 1
ThirdTable.Col1 -- Which is ThirdTable's Primary Key
FROM
ThirdTable
WHERE
ThirdTable.SomeColumn = JoinedTable.SomeColumn
) as ThirdTableColumn1,
(
SELECT TOP 1
ThirdTable.Col1 -- Which is also ThirdTable's Primary Key
FROM
ThirdTable
WHERE
ThirdTable.SomeOtherColumn = JoinedTable.SomeColumn
) as ThirdTableColumn2,
FROM
#TempTable as TempTable
LEFT JOIN
JoinedTable
ON (TempTable.PKColumn1 = JoinedTable.PKColumn1 AND
TempTable.PKColumn2 = JoinedTable.PKColumn2)
WHERE
JoinedTable.WhereColumn IN (1, 3)
Run Code Online (Sandbox Code Playgroud)
这是我的查询的精确副本。
如果我删除两个子选择,它运行得很好而且很快。通过两个子选择,我每秒得到大约 100 条记录,这对于这个查询来说非常慢,因为它应该返回近一百万条记录。
我已经检查过是否每张表都有一个主键,他们都有。它们都有重要列的索引和统计信息,就像那些 WHERE 子句中的那些,以及 JOIN …
我刚刚通过 DTA 运行了一个 T-SQL 查询,其中一项建议是在作为 SQL 代码文件中许多查询的一部分的列之一上创建统计信息。
我的问题是,统计数据究竟如何帮助提高性能?
只是想知道统计数据是否保存在数据库中而不是内存中?如果我将数据库从生产服务器备份/恢复到开发服务器,它是否会保留相同的统计信息,以便在开发服务器上执行计划不会有太大不同?
我是新手,试图围绕 OLAP 进行思考,我有几个问题。
我们的 IT 部门正在寻求有关特定 MS Analsis Services ROLAP 多维数据集出现的问题类型的反馈。我们无权访问其背后的关系数据库,需要执行当前无法作为多维数据集中度量的计算。
让我看看我是否有这个权利。
我正在阅读 Leland Wilkinson 的The Grammar of Graphics以及他关于数据挖掘和 OLAP 的章节,他说
这些 [立方体操作] 可以很好地处理诸如计数、均值、比例和标准差之类的统计数据。子类上的简单聚合可以通过对和、平方和和其他组合在线性函数中的项进行运算来计算,以生成基本的汇总统计。
它们不能与中位数、众数和百分位数等统计数据一起正常工作,因为这些统计数据的汇总不是它们汇总的统计数据。例如,中位数的中位数不是合计的中位数。
他接着补充说:
然而,最近出现了一种更复杂的 ROLAP 模型。通过多种技术,可以让统计算法通过关系模型实时访问原始数据。这种方法比数据立方体等结构提供的刚性聚合更有前途。
在这种架构的最优雅的形式中,应用程序可以请求远程连接以提供有关其数据处理方法的信息,并根据返回的信息采取适当的行动。在这种形式下,组件架构可以实现分布式计算的真正承诺:独立于站点、操作系统或语言的设计和执行。
那是大约 2005 年写的。有人知道使用这种方法来允许行级数据访问的产品吗?
我想在 PostgreSQL 中找到一个未排序列的 n>1 个百分位数。例如第 20、第 40、第 60、第 80 和第 100 个百分位数。
一个明显的解决方案是对列进行计数和排序,然后查看,但我希望有更好的解决方案。有任何想法吗?
PS 我找到了一个很好的 MySQL解决方案,但无法将其转换为 psql
我一直在研究我们数据库中运行缓慢的查询,并得出结论,这是一个经典的升序关键问题。由于几乎不断插入新行,并且每 30 分钟运行一次从数据库中提取最新数据的给定 SQL,每 30 分钟更新一次统计信息的第一个选项听起来可能会浪费资源。
因此,我查看了 Trace Flag 2389 原则上应该会有所帮助,但是这需要将 Lead 列标记为 Ascending,并且当我使用 Trace Flag 2388 检查(PK)索引统计信息时,我看到前导列实际上是标记为 Stationary - 因为它是同时更新的其他表上的几个 PK 索引。
似乎没有太多关于什么会导致固定品牌的指导,但是我确实发现KB2952101说如果少于 90% 的插入物大于旧的最大值,它将被归类为固定。我们所有的插入都是新提交的,前导列是一个 bigint IDENTITY 列,因此 100% 的插入应该大于先前的最大值。
所以我的问题是,当它明显是升序时,为什么该列会被标记为静止?
早期尝试为某些日常运行的 SQL(效果很好)解决此问题导致设置了一项作业来每晚更新此表的统计信息。更新不做全扫描,所以可能是采样扫描有时会丢失新行,所以它并不总是显示为升序?
我能想到的唯一可能会影响这一点的另一件事是,我们有一个存档作业在后台运行,删除超过特定年龄的行。这会影响品牌吗?
服务器是 SQL Server 2012 SP1。
更新:另一天,另一个统计数据更新 - 相同的固定品牌。自上次统计更新以来,已经有 28049 个新插入。每行都有一个插入时间的时间戳,所以如果我从表中选择 max(id) 其中 timestamp < '20161102' 我得到 23313455 同样,如果我在今天更新统计数据时这样做,我得到 23341504。
它们之间的区别在于 28049 个新插入,所以如您所见,所有新插入都被赋予了新的升序键(如预期),这表明前导列应该被标记为升序而不是固定。
在同一时期,我们的归档作业删除了 213,629 行(我们正在慢慢清除旧数据)。减少行数是否有可能有助于固定品牌?我之前测试过这个,它看起来没有任何区别。
更新 2:另一天,另一个统计数据更新,该列现在被标记为升序!根据有关删除影响的理论,我检查了与删除相比,插入更新的百分比,昨天 13% 是插入,而前两天插入约占 12%。我不认为这会给我们任何结论。
有趣的是,一个相关表平均每插入 4 行插入到这个主表中,并且同时更新了它的统计信息,它的 IDENTITY PK 列是否仍然是静止的!?
更新 3:在周末我们得到了更多的插入。今天早上领先的专栏回到了Stationary。在上一次统计更新中,我们有 46840 次插入,只有 …
我在这里寻找专家关于如何管理大约 18 TB 的非常大的数据库的更新统计信息的建议。
我们最近开始面临性能问题,并认为这是由于旧的统计数据造成的。
实际上,我们有一个作业运行 exec sp_update stats 并以默认采样率更新,在我们的例子中为 1.2%。所以我们必须手动更新统计数据并看到一些改进。
我相信安排 FULL SCAN 将是一个挑战。据我所知,我正在将行与采样的行进行比较。例如,在一张大小为 400 GB 且行数超过 100M 的表上,我可以看到采样行约为 2 到 4M。大表是分区的。
我们使用的是 SQL Server 2012 企业版。未启用跟踪标志 2371。
请建议我如何为如此大的数据库以更好的方式更新统计数据以及如何使用该采样率?
运行后ANALYZE myview;,我们是否应该在 PostgreSQL 9.6+ 物化视图上运行REFRESH MATERIALIZED VIEW CONCURRENTLY myview;?
或者它没有用(也许索引统计信息已经在刷新时更新了?)
我有一个 SQL Server 2017 (CU9) 数据库,它出现了一些我认为与索引统计有关的性能相关问题。在进行故障排除时,我发现统计信息尚未更新(意味着 DBCC SHOW_STATISTICS 将返回所有 NULL 值)。
我在受影响的表上执行 UPDATE STATISTICS 并验证 SHOW_STATISTICS 昨天下午 4:00 返回了实际值。今天早上 8:00AM 统计数据再次为空(返回 NULL 值)。
客户端确实有一项计划在每天凌晨 4:00 运行的维护作业,它为数据库重新索引,然后对整个数据库执行 sp_updatestats。我已经通过分析器跟踪验证了统计信息在凌晨 4:00 更新。
我不知道为什么统计数据会是空的,这是在凌晨 4:00 运行的维护工作吗?在此版本的 SQL Server 上是否存在我不知道的错误?
提前感谢你的帮助。
更多信息:
重新索引脚本(混淆):
USE DBNAME;
DECLARE @CERTENG_Lock INT
DECLARE @WebSite_Control_ProcessRunning_Lock INT
DECLARE @WebSite_Control_Disabled_Lock INT
DECLARE @LogMessage VARCHAR(1024)
SELECT @CERTENG_Lock = Lock FROM application.CERTENG_Lock
SELECT @WebSite_Control_Disabled_Lock = MAX(CAST(Disabled AS INT)),
@WebSite_Control_ProcessRunning_Lock = MAX(CAST(ProcessRunning AS INT))
FROM application.WebSite_Control
WHERE Webname = 'Reports'
IF(@CERTENG_Lock = …Run Code Online (Sandbox Code Playgroud) 信息
我的问题涉及一个中等大的表(~40GB 数据空间),它是一个堆
(不幸的是,我不允许应用程序所有者向该表添加聚集索引)
已创建 Identity 列 ( ID)上的自动创建统计信息,但该统计信息为空。
实际问题
据我了解,即使在完全相同的列(重复)上有两个统计数据,也可以使用所有统计数据并跟踪修改,那么为什么此统计数据仍为空?
统计信息
数据库统计信息
桌子尺寸
创建统计信息的列信息
[ID] [int] IDENTITY(1,1) NOT NULL
Run Code Online (Sandbox Code Playgroud)
身份栏
select * from sys.stats
where name like '%_WA_Sys_0000000A_6B7099F3%';
Run Code Online (Sandbox Code Playgroud)
获取有关另一个统计数据的一些信息
select * From sys.dm_db_stats_properties (1802541555, 3)
Run Code Online (Sandbox Code Playgroud)
与我的空数据相比:
来自“生成脚本”的统计数据 + 直方图:
/****** Object: Statistic [_WA_Sys_0000000A_6B7099F3] Script Date: 2/1/2019 10:18:19 AM ******/
CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
创建统计数据的副本时,里面没有数据
CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
手动更新统计信息时,它们确实会更新。
UPDATE STATISTICS …Run Code Online (Sandbox Code Playgroud)