我有以下架构(名称已更改),我无法更改:
CREATE TABLE MyTable (
Id INT NOT NULL PRIMARY KEY,
ParentId INT NOT NULL
);
ALTER TABLE MyTable ADD FOREIGN KEY (ParentId) REFERENCES MyTable(Id);
Run Code Online (Sandbox Code Playgroud)
也就是说,每条记录都是另一条记录的子项。如果记录的ParentId等于其Id,则该记录被视为根节点。
我想运行将找到所有循环引用的查询。例如,随着数据
INSERT INTO MyTable (Id, ParentId) VALUES
(0, 0),
(1, 0),
(2, 4),
(3, 2),
(4, 3);
Run Code Online (Sandbox Code Playgroud)
查询应该返回
Id | Cycle
2 | 2 < 4 < 3 < 2
3 | 3 < 2 < 4 < 3
4 | 4 < 3 < 2 < 4
Run Code Online (Sandbox Code Playgroud)
我为 SQL …
由于一些“开发人员”,我们在我们的系统上工作,我们遇到了空表的问题。我们发现在传输到云端的过程中,有几个表被复制了,但其中的数据没有。
我想运行一个查询系统表来查找哪些用户表是空的。我们使用的是 MS SQL 2008 R2。
谢谢您的帮助。
我是代理键的粉丝。我的发现存在确认偏倚的风险。
我在这里和http://stackoverflow.com 上看到的许多问题都使用自然键而不是基于IDENTITY()值的代理键。
我的计算机系统背景告诉我,对整数执行任何比较运算都比比较字符串快。
这个评论让我怀疑我的信念,所以我想我会创建一个系统来研究我的论点,即整数比字符串更快,用作 SQL Server 中的键。
由于小数据集可能几乎没有可辨别的差异,我立即想到了一个两表设置,其中主表有 1,000,000 行,而辅助表在主表中的每一行有 10 行,总共有 10,000,000 行。次要表。我的测试的前提是创建两组这样的表,一组使用自然键,一组使用整数键,并在简单的查询上运行计时测试,例如:
SELECT *
FROM Table1
INNER JOIN Table2 ON Table1.Key = Table2.Key;
Run Code Online (Sandbox Code Playgroud)
以下是我作为测试台创建的代码:
USE Master;
IF (SELECT COUNT(database_id) FROM sys.databases d WHERE d.name = 'NaturalKeyTest') = 1
BEGIN
ALTER DATABASE NaturalKeyTest SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE NaturalKeyTest;
END
GO
CREATE DATABASE NaturalKeyTest
ON (NAME = 'NaturalKeyTest', FILENAME =
'C:\SQLServer\Data\NaturalKeyTest.mdf', SIZE=8GB, FILEGROWTH=1GB)
LOG ON (NAME='NaturalKeyTestLog', FILENAME =
'C:\SQLServer\Logs\NaturalKeyTest.mdf', SIZE=256MB, FILEGROWTH=128MB); …Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2012 surrogate-key natural-key performance-testing
我正在尝试提高以下查询的性能:
UPDATE [#TempTable]
SET Received = r.Number
FROM [#TempTable]
INNER JOIN (SELECT AgentID,
RuleID,
COUNT(DISTINCT (GroupId)) Number
FROM [#TempTable]
WHERE Passed = 1
GROUP BY AgentID,
RuleID
) r ON r.RuleID = [#TempTable].RuleID AND
r.AgentID = [#TempTable].AgentID
Run Code Online (Sandbox Code Playgroud)
目前我的测试数据大约需要一分钟。我对这个查询所在的整个存储过程的更改的输入量有限,但我可能会让他们修改这个查询。或者添加索引。我尝试添加以下索引:
CREATE CLUSTERED INDEX ix_test ON #TempTable(AgentID, RuleId, GroupId, Passed)
Run Code Online (Sandbox Code Playgroud)
它实际上使查询所需的时间增加了一倍。我用非聚集索引得到了同样的效果。
我尝试按如下方式重新编写它,但没有任何效果。
WITH r AS (SELECT AgentID,
RuleID,
COUNT(DISTINCT (GroupId)) Number
FROM [#TempTable]
WHERE Passed = 1
GROUP BY AgentID,
RuleID
)
UPDATE [#TempTable]
SET Received = r.Number
FROM [#TempTable]
INNER JOIN r …Run Code Online (Sandbox Code Playgroud) 根据官方 Microsoft BOL DENSE_RANK 是不确定的(RANK())。但根据Itzik Ben-Gan 的排名函数 “...... RANK() 和 DENSE_RANK() 函数总是确定性的”。谁是对的?
到目前为止我发现: 微软的定义“确定性函数在任何时候使用一组特定的输入值调用它们时总是返回相同的结果,并给出相同的数据库状态。”
所以在集合理论表雇员
Employee Salary
Sue Right 1.00
Robin Page 1.00
Phil Factor 1.00
Run Code Online (Sandbox Code Playgroud)
和员工2
Employee Salary
Phil Factor 1.00
Sue Right 1.00
Robin Page 1.00
Run Code Online (Sandbox Code Playgroud)
是相同的。但是排名函数返回不同的值:
CREATE TABLE [dbo].[Employees](
--[ID] [int] IDENTITY(1,1) NOT NULL,
[Employee] [varchar](150) NOT NULL,
[Salary] [smallmoney] NULL,
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Employees2](
--[ID] [int] IDENTITY(1,1) NOT NULL,
[Employee] [varchar](150) NOT NULL,
[Salary] [smallmoney] NULL,
) ON …Run Code Online (Sandbox Code Playgroud) 在 SQL Server 2008 中缩小临时数据库时使用的最佳实践是什么?
使用以下方法有风险吗?
use tempdb
GO
DBCC FREEPROCCACHE -- clean cache
DBCC DROPCLEANBUFFERS -- clean buffers
DBCC FREESYSTEMCACHE ('ALL') -- clean system cache
DBCC FREESESSIONCACHE -- clean session cache
DBCC SHRINKDATABASE(tempdb, 10); -- shrink tempdb
dbcc shrinkfile ('tempdev') -- shrink db file
dbcc shrinkfile ('templog') -- shrink log file
GO
-- report the new file sizes
SELECT name, size
FROM sys.master_files
WHERE database_id = DB_ID(N'tempdb');
GO
Run Code Online (Sandbox Code Playgroud) 假设我有一个Foo包含列ID1, ID2和一个复合主键的表ID2, ID1。(我目前正在使用 System Center 产品,该产品具有以这种方式定义的多个表,主键列以它们在表定义中出现的相反顺序列出。)
CREATE TABLE dbo.Foo(
ID1 int NOT NULL,
ID2 int NOT NULL,
CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED (ID2, ID1)
);
GO
-- Add a row and update stats so that histogram isn't empty
INSERT INTO Foo (ID1, ID2) VALUES (1,2);
UPDATE STATISTICS dbo.Foo;
Run Code Online (Sandbox Code Playgroud)
的key_ordinal列sys.index_columns示出了它们在复合材料中的主键被宣布相同顺序的索引列:
SELECT t.name, i.name, c.column_id, c.name, ic.index_column_id, ic.key_ordinal
FROM sys.tables AS t
JOIN sys.indexes AS i
ON t.[object_id] = i.[object_id]
JOIN sys.index_columns …Run Code Online (Sandbox Code Playgroud) 我正在测试从聚集列存储索引中删除数据。
我注意到执行计划中有一个很大的eager spool操作符:
这完成了以下特征:
如果我欺骗估算器低估,我会得到一个更快的计划,避免使用 TempDB:
预计扫描成本:56.901
(这是一个估计的计划,但评论中的数字是正确的。)
有趣的是,如果我通过运行以下命令刷新增量存储,线轴会再次消失:
ALTER INDEX IX_Clustered ON Fact.RecordedMetricsDetail REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);
Run Code Online (Sandbox Code Playgroud)
只有当增量存储中的页面超过某个阈值时才会引入假脱机。
为了检查增量存储的大小,我正在运行以下查询来检查表的行内页:
SELECT
SUM([in_row_used_page_count]) AS in_row_used_pages,
SUM(in_row_data_page_count) AS in_row_data_pages
FROM sys.[dm_db_partition_stats] as pstats
JOIN sys.partitions AS p
ON pstats.partition_id = p.partition_id
WHERE p.[object_id] = OBJECT_ID('Fact.RecordedMetricsDetail');
Run Code Online (Sandbox Code Playgroud)
第一个计划中的假脱机迭代器是否有任何合理的好处?我不得不假设它是为了提高性能而不是为了万圣节保护,因为它的存在不一致。
我正在 2016 CTP 3.1 上对此进行测试,但我在 2014 SP1 CU3 上看到了相同的行为。
我已经发布了一个生成模式和数据的脚本,并指导您在此处演示问题。
这个问题主要是出于对优化器此时行为的好奇,因为我有一个解决方法来解决引发这个问题的问题(一个大的 spool 填充了 TempDB)。我现在通过使用分区切换来删除。
考虑 SQL Server 2014 中的以下查询计划:
在查询计划中,自联接ar.fId = ar.fId产生 1 行的估计值。然而,这是一个逻辑上不一致的估计:ar有20,608行和只有一个不同的值fId(准确地反映在统计数据中)。因此,此连接会生成行 ( ~424MMrows)的完整叉积,从而导致查询运行数小时。
我很难理解为什么 SQL Server 会得出一个很容易证明与统计数据不一致的估计值。有任何想法吗?
初步调查和其他细节
根据 Paul在此处的回答,用于估计连接基数的 SQL 2012 和 SQL 2014 启发式方法似乎都应该可以轻松处理需要比较两个相同直方图的情况。
我从跟踪标志 2363 的输出开始,但不太容易理解。请问下面的片段意味着SQL Server在比较直方图fId和bId以估计选择性的只加入使用fId?如果是这样,那显然是不正确的。还是我误读了跟踪标志输出?
Plan for computation:
CSelCalcExpressionComparedToExpression( QCOL: [ar].fId x_cmpEq QCOL: [ar].fId )
Loaded histogram for column QCOL: [ar].bId from stats with id 3
Loaded histogram for column QCOL: [ar].fId from stats with id 1 …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan sql-server-2014 cardinality-estimates query-performance
我需要找到一种方法来获取SUM()所有正值的所有正值num并返回SUM()所有正数的值和每个负数的单独行。下面是一个示例 DDL:
Create Table #Be
(
id int
, salesid int
, num decimal(16,4)
)
Insert Into #BE Values
(1, 1, 12.32), (2, 1, -13.00), (3, 1, 14.00)
, (4, 2, 12.12), (5, 2, 14.00), (6, 2, 21.23)
, (7, 3, -12.32), (8,3, -43.23), (9, 3, -2.32)
Run Code Online (Sandbox Code Playgroud)
这是我想要的输出(每个 salesid 的正数SUM()和负数得到单独的一行返回):
salesid num
1 26.32
1 -13.00
2 47.35
3 -12.32
3 -43.23
3 -2.32
Run Code Online (Sandbox Code Playgroud) sql-server ×10
performance ×2
columnstore ×1
foreign-key ×1
natural-key ×1
shrink ×1
statistics ×1
t-sql ×1
tempdb ×1