查看运行缓慢的查询的执行计划,我注意到有些节点是索引查找,有些是索引扫描。
索引查找和索引扫描有什么区别?
哪个表现更好?
SQL 如何选择一个?
我意识到这是 3 个问题,但我认为回答第一个会解释其他问题。
我们的一位开发人员添加了以下代码以从表中删除重复记录:
DELETE SubQuery
FROM
(
SELECT ID
,FK1
,FK2
,CreatedDateTime
,ROW_NUMBER() OVER(PARTITION BY FK1, FK2 ORDER BY CreatedDateTime) AS RowNumber
FROM Table
)
AS SubQuery
WHERE RowNumber > 1
Run Code Online (Sandbox Code Playgroud)
在查看代码时,我认为它不起作用,但是在我们的测试环境 (SQL 2014) 中测试它表明它起作用了!
SQL 如何知道解析子查询并从中删除记录table?
我正在尝试对 SQL Server 2014 Enterprise 中的查询进行性能优化。
我已经在 SQL Sentry Plan Explorer 中打开了实际的查询计划,我可以在一个节点上看到它有一个Seek Predicate和一个Predicate
什么之间的区别寻求谓词和谓词?
注意:我可以看到这个节点有很多问题(例如估计行与实际行、剩余 IO),但问题与任何这些都无关。
performance execution-plan sql-server-2014 query-performance
我有一个通过 SQL Server 代理(运行 SQL Server 2012 Enterprise)运行的 SQL 作业。作业的最后一步是运行位于网络共享上的应用程序。不幸的是,我不知道应用程序所在文件夹的名称(文件夹是版本号),所以我使用 PowerShell 来查找它:
set-location "\\server\companydocuments\MyApp\Application Files\"
$name = Get-ChildItem | sort name -desc | select -f 1 | select name
cd $name.name
& ".\Application.exe"
Run Code Online (Sandbox Code Playgroud)
如果我在 SQL Server 上打开一个 PowerShell 窗口,那么它工作正常。当我在 SQL Server 代理中运行它时,出现以下错误:
A job step received an error at line 1 in a PowerShell script.
The corresponding line is 'set-location "\\server\companydocuments\MyApp\Application Files\'"
Run Code Online (Sandbox Code Playgroud)
我认为这可能是权限问题,所以我尝试在我的凭据下运行 SQL Server 代理(它是测试服务器,而不是生产服务器),但我仍然遇到相同的错误。我还尝试将网络驱动器映射到共享文件夹而不是 UNC 路径,但出现相同的错误。
谁能建议我如何连接到这个文件夹?
我们正在构建一个新的生产 Windows Server 2012 R2 服务器来运行 SQL Server 2014 企业版。
互联网上有一些建议,建议 Windows Server 2012 和 SQL Server 2012 我应该坚持使用 NTFS(例如itknowledgeexchange),因为像DBCC CHECKDB这样的数据库命令不起作用。
但是,也有人建议 SQL Server 2014 现在支持 ReFS(例如Brent Ozar、msdn social)
在 SQL 2014 和 Server 2012 R2 中是否有关于何时使用 NTFS 以及是否/何时使用 ReFS 的数据和日志文件的建议或一般经验法则?
我们正在考虑在 SQL 2012 中使用变更数据捕获。我们试图找出是否有一种简单的方法来找出给定 lsn 更改了哪些表。是否有内置函数,或者我们是否需要查询每个 cdc 表以查看 lsn 是否在其中?
更新更多地解释我们正在尝试做的事情:
我们正在尝试构建一个过程来查看数据库中所有表的 cdc 数据(想想 100 个)。此进程将按计划运行,并且会知道它处理的最后一个 lsn。当它运行时,我们想对自上次记录的 lsn 以来发生变化的每个 cdc 表做一些事情。
我们可以检查fn_cdc_get_all_changes_dbo_tablename(@lastlsn, @currentlsn, 'all'),但问题是我们必须运行它 100 次(每个表一次)。有我们可以检查的中心位置吗?
我正在查看我们的数据库并注意到在特定表上我们有以下索引:
表:
Col1 INT IDENTITY(1,1) Primary Key
Col2 INT
...
about 15 more columns
....
ColN VARCHAR(50)
....
another 10 more columns
Run Code Online (Sandbox Code Playgroud)
除了标准的主键聚集索引之外Col1,我们还有以下索引:
create nonclustered index [iTable-Col1] ON [dbo].[Table1]
(
Col1
)
include ( ColN )
Run Code Online (Sandbox Code Playgroud)
我们定期搜索Col1并且只想检索ColN. 该索引确实得到使用,因为它是包含满足查询所需的所有数据的最小索引。
我的问题是,这个索引对 SQL Server 有什么好处吗?我们最好放弃它并只在聚集索引上进行搜索吗?
我唯一的想法是这个索引比聚集索引(25mb vs 300mb)小得多,这可能会使搜索和/或缓存更快。
如果有任何区别,服务器是 SQL Server 2012。
我从其他问题和帖子中知道,当 SQL 编译查询计划时,它只能使用过滤索引,前提是保证每次查询运行时都可以使用过滤索引。这意味着您不能在 where 子句中使用变量,因为有时它可能能够使用过滤索引,有时则不能。
解决此问题的一种方法是使用OPTION(RECOMPILE),以便它可以使用它的次数,它将获得过滤后的索引。
做一些测试,我发现这个查询可以使用过滤索引(注意,我强制使用索引只是为了证明一个观点):
SELECT MAX(table1.SomeDateField)
FROM dbo.table1 WITH(INDEX(MyFilteredIndex))
WHERE table1.filteredColumn = @variable
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)
但是,如果我想将结果分配给一个变量,我就不走运了:
SELECT @OutputVariable = MAX(table1.SomeDateField)
FROM dbo.table1 WITH(INDEX(MyFilteredIndex))
WHERE table1.filteredColumn = @variable
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)
结果是:
消息 8622,级别 16,状态 1,第 15 行 由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用 SET FORCEPLAN 的情况下重新提交查询。
当我不想将输出保存到变量时,查询可以清楚地使用过滤后的索引,因为它运行 find 。
我有办法将此查询重写为硬编码@variable以消除问题,但有人可以解释为什么第一个查询可以使用过滤索引,而第二个查询不能?
我有一个超过一百万行的表。这些行可以在同一个表中有一个父记录,通过在 6 个不同的列上连接到它自己(即没有单列ParentID)。根据这些连接,每个孩子都恰好有 1 个父级,并且每个记录要么是父级记录,要么是子级记录(即没有祖父级记录)。
SELECT *
FROM TheTable AS ChildRecords
JOIN TheTable AS ParentRecords
ON ChildRecords.Column1 = ParentRecords.Column1
AND ChildRecords.Column2 = ParentRecords.Column2
AND ChildRecords.Column3 = ParentRecords.Column3
AND ChildRecords.Column4 = ParentRecords.Column4
AND ChildRecords.Column5 = ParentRecords.Column5
AND ChildRecords.Column10 = ParentRecords.Column6
Run Code Online (Sandbox Code Playgroud)
注意第 10 列连接到第 6 列,但该列本身没有找到唯一的父级 - 可能有多个带有column10= 的“父级” column6。
这通常工作正常,但是如果我们将它作为更大查询的一部分,SQL Server 通常会先尝试解析此连接,然后再解析其他连接。当它处于 CTE 或加入 CTE 时尤其如此。它通常是查询计划中发生的第一个连接。这通常会导致数以万计的连接,然后再过滤到我感兴趣的 100 条左右的记录。发生这种情况时,查询需要几分钟才能运行。
我注意到我可以通过使其成为左连接来影响查询计划。这是有道理的,因为如果它是左联接,那么 SQL Server 不知道每个孩子都有 1 个父级,因此它总是必须首先找到子级记录。
SELECT *
FROM TheTable AS ChildRecords
LEFT JOIN TheTable AS ParentRecords
ON …Run Code Online (Sandbox Code Playgroud) 使用 AlwaysOn 可用性组时,每个 SQL 实例是否需要使用相同的服务凭据?
我们正在设置新的 SQL2014 部署,并将使用 AlwaysOn。如果我有 2 个 SQL 服务器(称为 ServerA 和 ServerB),那么我可以使用 2 个名为 Domain\ServerA_SQLServerService 和 Domain\ServerB_SQLServerService 的活动目录帐户(每个服务器上一个)吗?
或者他们是否需要使用相同的帐户,所以我应该创建 Domain\SQLServerService
这些帐户将在同一个域中,并且可以访问两台服务器。以前我们已经锁定了 SQL Server 服务帐户,这显然导致了问题。我想要做的是拥有 2 个帐户,以便减少两个帐户被锁定的可能性。
是否有要求和/或 Microsoft 的最佳实践是什么?
sql-server availability-groups sql-server-2014 service-accounts
sql-server ×8
index ×3
performance ×3
hints ×1
index-tuning ×1
jobs ×1
join ×1
powershell ×1
storage ×1
subquery ×1