我只是在看StackOverflow上的一篇文章,其中 Aaron Bertrand 建议使用 CTE 而不是数字表,这是执行手头任务的一种优雅方式。我的问题是,为什么 CTE 的第一行以分号开头?
;WITH n AS (SELECT TOP (10000) n FROM
(SELECT n = ROW_NUMBER() OVER
(ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!
Run Code Online (Sandbox Code Playgroud)
这是为了确保 WITH 语句不会被解析为以前的内容SELECT或其他内容吗?我在 SQL Server 2005 BOL 中没有看到关于在 WITH 之前使用分号的内容。
我有一个 SQL 查询,我花了两天时间尝试使用试错法和执行计划进行优化,但无济于事。请原谅我这样做,但我会在这里发布整个执行计划。我已经努力使查询和执行计划中的表名和列名通用,既为了简洁又为了保护我公司的 IP。可以使用SQL Sentry Plan Explorer打开执行计划。
我已经完成了大量的 T-SQL,但是使用执行计划来优化我的查询对我来说是一个新领域,我真的试图了解如何去做。所以,如果有人能帮我解决这个问题并解释如何破译这个执行计划以在查询中找到优化它的方法,我将永远感激不尽。我还有更多的查询需要优化——我只需要一个跳板来帮助我完成第一个查询。
这是查询:
DECLARE @Param0 DATETIME = '2013-07-29';
DECLARE @Param1 INT = CONVERT(INT, CONVERT(VARCHAR, @Param0, 112))
DECLARE @Param2 VARCHAR(50) = 'ABC';
DECLARE @Param3 VARCHAR(100) = 'DEF';
DECLARE @Param4 VARCHAR(50) = 'XYZ';
DECLARE @Param5 VARCHAR(100) = NULL;
DECLARE @Param6 VARCHAR(50) = 'Text3';
SET NOCOUNT ON
DECLARE @MyTableVar TABLE
(
B_Var1_PK int,
Job_Var1 varchar(512),
Job_Var2 varchar(50)
)
INSERT INTO @MyTableVar (B_Var1_PK, Job_Var1, Job_Var2)
SELECT B_Var1_PK, Job_Var1, Job_Var2 FROM [fn_GetJobs] (@Param1, @Param2, @Param3, @Param4, …Run Code Online (Sandbox Code Playgroud) sql-server-2008 sql-server optimization t-sql execution-plan
假设我有两个查询,在 SSMS 中的两个单独会话中运行:
第一节:
UPDATE Person
SET Name='Jonny', Surname='Cage'
WHERE Id=42
Run Code Online (Sandbox Code Playgroud)
第二场:
SELECT Name, Surname
FROM Person WITH(NOLOCK)
WHERE Id > 30
Run Code Online (Sandbox Code Playgroud)
SELECT语句是否有可能读取半更新的行,例如带有Name = 'Jonny'和的行Surname = 'Goody'?
查询几乎在不同的会话中同时执行。
查看Kalen Delaney 撰写的“SQL Server 2008 Internals” 1,第 13 页,它说明了以下内容:
“生成这样一个计划的第一步是规范化每个查询,这可能会将单个查询分解为多个细粒度的查询。查询优化器在规范化一个查询之后对其进行优化,这意味着它确定了一个计划执行该查询。”
另一位 DBA 向我建议,可以通过将WHERE子句谓词移动到FROM子句中来提高某些查询的性能,例如:
SELECT *
FROM dbo.table1 t1
INNER JOIN dbo.table3 t3 ON t1.ID = t3.ID
LEFT OUTER JOIN dbo.table2 t2 ON t1.ID = t2.ID
WHERE t1.CreateDate >= '2015-07-31 00:00:00';
Run Code Online (Sandbox Code Playgroud)
会成为:
SELECT *
FROM dbo.table1 t1
INNER JOIN dbo.table3 t3 ON t1.ID = t3.ID
AND t1.CreateDate >= '2015-07-31 00:00:00'
LEFT OUTER JOIN dbo.table2 t2 ON t1.ID = t2.ID;
Run Code Online (Sandbox Code Playgroud)
显然,第一个示例的含义是查询优化器将执行第JOIN一个, …
我的数据库大于 250GB。我使用第三方工具进行计划备份。
计划数据库备份是保护 SQL Server 数据库免受损坏的最佳方法吗?或者你能推荐其他东西吗?
查询sys.dm_tran_locksDMV 会向我们显示哪些会话 (SPID) 持有表、页和行等资源的锁。
对于获取的每个锁,是否有任何方法可以确定导致该锁的 SQL 语句(删除、插入、更新或选择)?
我知道,most_recent_query_handle在列sys.dm_exec_connectionsDMV给了我们执行的最后一个查询的文本,而是多次其他查询同一个会话(SPID)在跑前和仍持有锁。
我已经使用了这个sp_whoisactive过程(来自 Adam Machanic),它只显示了此时输入缓冲区上的查询(想想DBCC INPUTBUFFER @spid),这并不总是(在我的情况下通常永远不会)是获取锁的查询。
例如:
该sp_whoisactive过程将指出第 3 步中的语句,该语句不是锁的负责人,因此没有用。
这个问题来自使用Blocked Process Reports功能进行分析,以找出生产中阻塞场景的根本原因。每个事务运行多个查询,并且大多数时候最后一个(显示在 BPR 的输入缓冲区中)很少是持有锁的那个。
我有一个后续问题:有效识别阻塞查询的框架
我正在尝试使用两个原始(即未格式化)分区创建数据库。
Microsoft Docs 声明您可以执行此操作,您只需指定原始分区的驱动器号,如下所示:
CREATE DATABASE DirectDevice
ON (NAME = DirectDevice_system, FILENAME = 'S:')
LOG ON (NAME = DirectDevice_log, FILENAME = 'T:')
Run Code Online (Sandbox Code Playgroud)
但是,SQL Server 2017 返回此错误:
消息 5170,级别 16,状态 4,第 1 行
无法创建文件“S:”,因为它已经存在。更改文件路径或文件名,然后重试该操作。
消息 1802,级别 16,状态 4,第 1 行
创建数据库失败。无法创建列出的某些文件名。检查相关错误。
文档的相关部分指出:
如果文件位于原始分区上,则 os_file_name 必须仅指定现有原始分区的驱动器号。每个原始分区上只能创建一个数据文件。
是的,驱动器 S: 和 T: 都是未格式化的原始分区,它们确实存在于我的系统中:
DISKPART> 详细分区 分区 4 类型:ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 隐藏:否 要求:否 属性:0000000000000000 以字节为单位的偏移量:999934656512 卷 ### Ltr 标签 Fs 类型大小状态信息 ---------- --- ----------- ----- ---------- ------- ---- ----- -------- * 第 6 卷 T RAW …
在工作原理:SQL Server 2012 数据库引擎任务计划中,Bob Dorr 解释了 SQL Server 2012 中工作调度程序分配的一些更改。他提到一些改进仅在企业版中可用。这些差异在 SQL Server 2019 中是否仍然存在?
如果这很重要,我会问这个问题,因为我发现 SQL Server 2017 标准版实例上可能存在调度程序效率低下的问题,该实例计划未来升级到企业版。如果升级到企业版可以解决问题,我不想尝试对标准版进行调查。
我们的一款产品同时支持 Oracle 和 SQL Server 作为数据库后端。我们有一位客户希望从 Oracle 后端切换到 Microsoft SQL Server,这对我们来说不是典型的过渡。
将整个 Oracle Schema 中的所有数据获取到 SQL Server 数据库中的最简单方法是什么?
模式只包含普通的旧表,没有什么花哨的。可能有一两个存储过程,我们手动迁移不会有问题。
我可以使用 Oracle 的 SQLDeveloper 将表数据导出为CREATE和INSERT语句,但这些与 SQL Server 上使用的语法不匹配,我不希望手动修复语法错误。
我正在查看计划缓存,寻找低悬的优化成果,并发现了以下代码段:

为什么很多费用都在 100% 以上?那应该是不可能的吧?
sql-server ×10
optimization ×2
syntax ×2
t-sql ×2
backup ×1
blocking ×1
concurrency ×1
cte ×1
locking ×1
migration ×1
oracle ×1
ssms ×1
storage ×1