SQL Server 2014,标准版
我已经读过 dm_exec_requests 中的 percent_complete 不适用于 CREATE INDEX,实际上,percent_complete 坚持为 0。所以这没有帮助。
我目前使用下面的方法,它至少显示了我的运动(索引创建没有被阻止)。但是我完全不知道我是 %10 还是 %99。
我尝试了这里描述的方法:https : //dba.stackexchange.com/a/102545/6229 但它显示了一个明显错误的 est 完成时间(它基本上显示了一个 60+ 分钟的过程的“现在”,我进入了 10 分钟)
我怎样才能得到线索?
SELECT percent_complete, estimated_completion_time, reads, writes, logical_reads, text_size, *
FROM
sys.dm_exec_requests AS r
WHERE
r.session_id <> @@SPID
AND r.session_id = 58
Run Code Online (Sandbox Code Playgroud) 我有两个具有相同名称、类型和索引键列的表。其中一个具有唯一的聚集索引,另一个具有非唯一的.
测试设置
设置脚本,包括一些真实的统计数据:
DROP TABLE IF EXISTS #left;
DROP TABLE IF EXISTS #right;
CREATE TABLE #left (
a char(4) NOT NULL,
b char(2) NOT NULL,
c varchar(13) NOT NULL,
d bit NOT NULL,
e char(4) NOT NULL,
f char(25) NULL,
g char(25) NOT NULL,
h char(25) NULL
--- and a few other columns
);
CREATE UNIQUE CLUSTERED INDEX IX ON #left (a, b, c, d, e, f, g, h)
UPDATE STATISTICS #left WITH ROWCOUNT=63800000, PAGECOUNT=186000;
CREATE …Run Code Online (Sandbox Code Playgroud) join sql-server sql-server-2014 sort-operator sql-server-2017
我有一个我无法理解的情况。我的 SQL Server 执行计划告诉我,我缺少表上的统计信息,但统计信息已经创建:

但是如果我们查看表格,我们会看到有一个自动创建的统计信息:

有人可以帮助理解它是怎么回事吗?
Auto_Update 和 Auto_Create 统计信息在当前数据库上打开。
我正在使用 SQL Server 2014。
通常,当我在新环境中开始时,我倾向于检查备份在哪里,最后一次完整的时间,最后一次应用的还原时间,我也会检查安全性。
我这样做的方式是通过 T-SQL。
检查备份
;with Radhe as (
SELECT @@Servername as [Server_Name],
B.name as Database_Name,
ISNULL(STR(ABS(DATEDIFF(day, GetDate(), MAX(Backup_finish_date)))), 'NEVER') as DaysSinceLastBackup,
ISNULL(Convert(char(11), MAX(backup_finish_date), 113)+ ' ' + CONVERT(VARCHAR(8),MAX(backup_finish_date),108), 'NEVER') as LastBackupDate
,BackupSize_GB=CAST(COALESCE(MAX(A.BACKUP_SIZE),0)/1024.00/1024.00/1024.00 AS NUMERIC(18,2))
,BackupSize_MB=CAST(COALESCE(MAX(A.BACKUP_SIZE),0)/1024.00/1024.00 AS NUMERIC(18,2))
,media_set_id = MAX(A.media_set_id)
,[AVG Backup Duration]= AVG(CAST(DATEDIFF(s, A.backup_start_date, A.backup_finish_date) AS int))
,[Longest Backup Duration]= MAX(CAST(DATEDIFF(s, A.backup_start_date, A.backup_finish_date) AS int))
,A.type
FROM sys.databases B
LEFT OUTER JOIN msdb.dbo.backupset A
ON A.database_name = B.name
AND A.is_copy_only = 0
AND (A.type = 'D') --'D' full, 'L' …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
在下面的查询中,估计两个执行计划对唯一索引执行 1,000 次搜索。
查找是由对同一源表的有序扫描驱动的,因此看起来最终应该以相同的顺序查找相同的值。
两个嵌套循环都有 <NestedLoops Optimized="false" WithOrderedPrefetch="true">
任何人都知道为什么这个任务在第一个计划中的成本为 0.172434,而在第二个计划中为 3.01702?
(问题的原因是第一个查询被建议作为优化,因为计划成本明显低得多。它实际上在我看来好像它做了更多的工作,但我只是试图解释这种差异.. .)
CREATE TABLE dbo.Target(KeyCol int PRIMARY KEY, OtherCol char(32) NOT NULL);
CREATE TABLE dbo.Staging(KeyCol int PRIMARY KEY, OtherCol char(32) NOT NULL);
INSERT INTO dbo.Target
SELECT TOP (1000000) ROW_NUMBER() OVER (ORDER BY @@SPID), LEFT(NEWID(),32)
FROM master..spt_values v1,
master..spt_values v2;
INSERT INTO dbo.Staging
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY @@SPID), LEFT(NEWID(),32)
FROM master..spt_values v1;
Run Code Online (Sandbox Code Playgroud)
WITH T
AS (SELECT *
FROM Target AS T
WHERE T.KeyCol …Run Code Online (Sandbox Code Playgroud) 我有一个关于XTP_CHECKPOINT.
我使用的是 SQL Server 2014。我有一个处于 SIMPLE 恢复模式模式的数据库。它也在被复制。
没有未结交易。我跑了DBCC OPENTRAN,它返回:
“没有活跃的未结交易。”
但是每当我尝试创建或删除表或删除数据时,我都会收到此消息:(
我已将实际数据库名称替换为单词database_name)
“由于 'XTP_CHECKPOINT',数据库 'database_name' 的事务日志已满”
有谁知道为什么会发生这种情况,更重要的是,我怎样才能让它停止?
是的,数据库确实处于 SIMPLE 恢复模式模式。即事务日志应自动截断。
顺便说一句,我在完全恢复模式下的另一个数据库做了同样的事情,开始返回相同的错误:
由于“XTP_CHECKPOINT”,数据库“database_name”的事务日志已满
我试图将日志增长设置更改为无限增长,但它不会让我返回相同的错误。
除了文件组之外,我可以在没有任何 XTP 内容的情况下重现该问题。方法如下:http : //pastebin.com/jWSiEU9U
sql-server transaction-log sql-server-2014 memory-optimized-tables
我有一个带有字符串列的表和一个检查具有特定长度的行的谓词。在 SQL Server 2014 中,无论我检查的长度如何,我都会看到估计为 1 行。这产生了非常糟糕的计划,因为实际上有数千甚至数百万行,而 SQL Server 选择将此表放在嵌套循环的外侧。
对于 SQL Server 2014 的基数估计为 1.0003 而 SQL Server 2012 估计为 31,622 行,是否有解释?有没有好的解决方法?
以下是该问题的简短再现:
-- Create a table with 1MM rows of dummy data
CREATE TABLE #customers (cust_nbr VARCHAR(10) NOT NULL)
GO
INSERT INTO #customers WITH (TABLOCK) (cust_nbr)
SELECT TOP 1000000
CONVERT(VARCHAR(10),
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS cust_nbr
FROM master..spt_values v1
CROSS JOIN master..spt_values v2
GO
-- Looking for string of a certain length.
-- While both CEs …Run Code Online (Sandbox Code Playgroud) sql-server varchar functions sql-server-2014 cardinality-estimates
我有以下MERGE针对数据库发出的语句:
MERGE "MySchema"."Point" AS t
USING (
SELECT "ObjectId", "PointName", z."Id" AS "LocationId", i."Id" AS "Region"
FROM @p1 AS d
JOIN "MySchema"."Region" AS i ON i."Name" = d."Region"
LEFT JOIN "MySchema"."Location" AS z ON z."Name" = d."Location" AND z."Region" = i."Id"
) AS s
ON s."ObjectId" = t."ObjectId"
WHEN NOT MATCHED BY TARGET
THEN INSERT ("ObjectId", "Name", "LocationId", "Region") VALUES (s."ObjectId", s."PointName", s."LocationId", s."Region")
WHEN MATCHED
THEN UPDATE
SET "Name" = s."PointName"
, "LocationId" = s."LocationId"
, "Region" …Run Code Online (Sandbox Code Playgroud) sql-server ×10
sql-server-2014 ×10
backup ×1
columnstore ×1
functions ×1
index ×1
join ×1
merge ×1
optimization ×1
performance ×1
restore ×1
security ×1
statistics ×1
varchar ×1