我有一个在可接受的时间内运行的查询,但我想从中榨取最大的性能。
我试图改进的操作是计划右侧的“索引搜索”,来自节点 17。
我已经添加了适当的索引,但我为该操作获得的估计值是它们应有的值的一半。
我一直在寻找更改我的索引并添加一个临时表并重新编写查询,但为了获得正确的估计,我无法简化它。
有没有人对我可以尝试的其他方法有任何建议?
更新:
我有一种感觉,这个问题的初始版本引起了很多混乱,所以我将添加带有一些解释的原始代码。
create procedure [dbo].[someProcedure] @asType int, @customAttrValIds idlist readonly
as
begin
set nocount on;
declare @dist_ca_id int;
select *
into #temp
from @customAttrValIds
where id is not null;
select @dist_ca_id = count(distinct CustomAttrID)
from CustomAttributeValues c
inner join #temp a on c.Id = a.id;
select a.Id
, a.AssortmentId
from Assortments a
inner join AssortmentCustomAttributeValues acav
on a.Id = acav.Assortment_Id
inner join CustomAttributeValues cav
on cav.Id = acav.CustomAttributeValue_Id
where a.AssortmentType = …Run Code Online (Sandbox Code Playgroud) 我知道有一些问题可以解决数据库卡在RESTORING状态的问题,并且已经使用这些解决方案手动使数据库重新联机,但我的情况有些不同。
我使用 Powershell 脚本进行自动恢复,该脚本将生产副本恢复到 DEV 实例。脚本大约一年没有变化,偶尔恢复过程完成但恢复的数据库卡在RESTORING状态(有时脚本工作正常,有时会像这样失败)。
每次如果我手动重新运行该过程,它就会工作,或者如果我从 SSMS 的用户界面或通过 T-SQL 手动恢复数据库,它都会毫无问题地完成。
我找到了建议CHECKDB在恢复的数据库上运行的答案,但没有发现导致此问题的原因。
由于恢复脚本恢复了数据库的完整备份并使用了一个"WITH RECOVERY"选项,我试图找出可能会停止恢复过程的原因,尽管我实际上是使用"WITH RECOVERY".
任何建议都非常感谢,因为我一直试图理解为什么会不时发生这种情况。
我很想解决问题的根本原因而不是治标,即再次手动恢复数据库。
更新:
正如@Brent 推荐的那样,Github Gist在这里。
我有一个 SQL 查询,它是由一堆嵌套的视图和表值函数组成的,深度至少为 4 层(我没有时间或耐心去完成这一切,它有数百行代码在每个级别)。
我一直试图理解为什么当我使用选项(重新编译)运行基本查询时它运行得非常快,但是当我在没有这个选项的情况下运行它时,它运行得非常慢。
我已确保在发生这种情况之前清除计划缓存,即使在生成新计划时,它也不是最佳的,但是,选项(重新编译)速度很快。
我检查了这两个计划,并注意到对于带有选项(重新编译)的计划,传递的参数。
SELECT [p].[Activity]
,[p].[ActivityType]
,[p].[Company]
,[p].[Flags]
,[p].[Id]
,[p].[Name]
,[p].[Priority]
,[p].[Filters]
,[p].[Priority]
,[p].[Classification]
,[p].[Number]
,[p].[TaskFilter]
,[p].[TaskType]
,[p].[User]
FROM (
SELECT *
FROM [ActivProdStatuses]('ProdJobTask', 0)
) AS [p]
WHERE (
( ([p].[User] = 'some_value') AND (([p].[Flags] & 8) = 0) )
AND ([p].[Activity] = 'unique_value')
)
AND
(CASE
WHEN ([p].[Flags] & 4) <> 0
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT)
END = 1 )
ORDER BY [p].[Priority]
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)
在没有 OPTION …
sql-server execution-plan azure-sql-database recompile query-performance
我遇到了一个很奇怪的问题。我正在运行相同的脚本来生成数据并稍后在较旧的 2008R2 实例上进行一些匹配。最后一个查询(一个UPDATE ) 执行单个表扫描并返回所有 250.000 行,而在较新的 2017 实例上,该表是并行扫描的,4 个线程中的每一个都读取 250.000 行,并返回 100 万“实际读取行”。
我在 2017 年的实例中将兼容模式更改为 2008 年,实际值保持不变,为 1.000.000。
为什么会发生这种情况是否有任何正当理由,或者这似乎应该是一个 Connect 项目?
计划包含相同的运算符,但其中一个执行并行扫描,而不是将 250.000 行拆分为 4 个线程中的每一个(并且每个线程仅读取 62.500 行)所有线程读取 250k,每个 *4 = 1.000.000
两个执行计划都可以在 pastetheplan 找到:
此外,我正在运行的完整脚本可以在下面找到:
create table #targets (id int identity(1,1), start_point int, end_point int, refference_type_id int, bla1 int, bla2 int, bla3 int, bla4 int, bla5 int, bla6 int, bla7 int, bla8 int, bla9 bit, assignedTouch varchar(10));
;with cte as (
select
1 …Run Code Online (Sandbox Code Playgroud) sql-server execution-plan sql-server-2008-r2 sql-server-2017
即使写标题,我也对我尝试过的想法感到畏缩(但是,嘿,我在这个过程中学到了一些东西)。
我遇到了一个问题,开发人员在数据库上运行迁移脚本并在此过程中覆盖数据库中已经存在的存储过程(DEV,感谢上帝)。
但是,无法找出谁进行了这些更改,因为:
所以,我尝试在 sys.objects 上写一个触发器,但没有奏效(我不知道为什么我曾经期望它),因为我收到了一个错误:
对象“DEV_DB.sys.objects”不存在或对于此操作无效。
我还尝试为每个开发人员创建一个用户,这样当他们进行自动迁移时,他们将使用我创建的用户,希望sys.objects该开发人员所做的所有更改都将作为他们登录的用户记录。
但是,这并不能工作,因为principal_id还没有填充(我所做的一切就是为每一个开发者&DB新的登录/用户,并赋予登录特定服务器角色:public,db_datawriter,db_datareader,db_ddladmin)。
关于我还可以尝试什么作为替代方案的任何建议?
我正在尝试编写查询以查找有关特定存储过程的查询统计信息和查询计划的信息,但我无法找到正确的 DMV 或查询来查找特定存储过程。
到目前为止,我有:
select
qs.sql_handle
, qs.statement_start_offset
, qs.statement_end_offset
, qs.plan_handle
, execution_count
, st.text
, substring(st.text, (qs.statement_start_offset/2)+1,
((case qs.statement_end_offset
when -1
then datalength(st.text)
else
qs.statement_end_offset
end - qs.statement_start_offset) / 2 + 1)) as [Filtered text]
, qp.query_plan
from sys.dm_exec_query_stats as qs
cross apply sys.dm_exec_sql_text (qs.sql_handle) as st
cross apply sys.dm_exec_query_plan (qs.plan_handle) as qp
where st.text like '%myProcedure%'
order by qs.sql_handle
, execution_count desc
Run Code Online (Sandbox Code Playgroud)
但是这个查询不返回任何信息。理想情况下,我会st.text like用类似的东西替换条件object_name(procedure_id) = 'myProcedure',但我找不到正确的方法。
有没有更好的方法来做到这一点?
我可以WHERE用 a替换子句中的条件,qs.sql_handle = …
我有一个在使用时正在运行的存储过程,SET STATISTICS TIME ON该过程的总体执行时间为 31 秒,但是在查看来自 的信息时STATISTICS TIME,将每个查询的所有经过时间相加的结果大于 31秒。
例如:
SQL Server Execution Times: CPU time = 109 ms, elapsed time = 128 ms.
SQL Server Execution Times: CPU time = 156 ms, elapsed time = 159 ms.
SQL Server Execution Times: CPU time = 1528 ms, elapsed time = 15901 ms.
SQL Server Execution Times: CPU time = 1248 ms, elapsed time = 8055 ms.
SQL Server Execution Times: CPU time = 6037 ms, elapsed …Run Code Online (Sandbox Code Playgroud) 我一直在尝试为一个测试场景运行一些查询,我注意到在对非聚集索引进行全面扫描时,SQL Server 读取的页面比索引中的实际页面多。
从下图可以看出,我的查询是(一个简单的):
select
sometext
, somemoretext
from tbl
Run Code Online (Sandbox Code Playgroud)
我有这些列的精确覆盖非聚集索引。
在 Profiler 中,为此读取的页数22,356如您在图像中所见。
但是查看索引详情的时候,在Fragmentation下,这个索引的页数是22,278。
读取页面差异的原因是什么(78准确地说)?Fragmentation 部分中的数字是不可靠的还是有其他解释?
索引没有碎片(或似乎没有),所以没有比那些更多的页面了22,278……或者有吗?我无法在网上、微软网站或其他网站上找到对此的解释。
(这是一个受控环境,在为这个问题截屏时,表上没有发生插入和删除)
我也把计划贴在这里。
我正在尝试恢复测试数据库的差异备份,但我收到一条错误消息:
我所做的是创建了一个名为 的测试数据库,"tdb"我在新表中添加了一些数据,将数据库的恢复模型更改为SIMPLE,然后创建了一个FULL Backup.
之后,我将更多数据添加到新表中,并继续制作differential backup.
恢复数据库时,我首先恢复了完整备份,Overwrite existing database (WITH REPLACE)从 SSMS 中选择了正确运行的选项。
然后,当尝试对差异备份文件执行相同操作时,出现上述错误。
我也查看了 Microsoft 文档,并按照那里提到的相同步骤进行了操作,但是我看不出我做错了什么。任何帮助表示赞赏。
我想知道是否有一个表可以保存每个用户或每个系统对表的访问。
我同时使用 SQL Server 2005 和 2008。
我有一个使用SqlRestoreAsync方法恢复数据库的 Powershell 脚本。
我有一个大小适中的数据库,我正在恢复(~55Gb),我正在尝试查找恢复过程的进度。
我知道,如果我通过 T-SQL 命令运行恢复,那么我可以通过查询一些 DMV 或使用以下查询来查看恢复的进度:
SELECT r.session_id
, r.command
, CONVERT(NUMERIC(6, 2), r.percent_complete) AS [Percent Complete]
, CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time, GetDate()), 20) AS [ETA Completion Time]
, CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [Elapsed Min]
, CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETA Min]
, CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0 / 60.0) AS [ETA Hours]
, CONVERT(VARCHAR(1000), (
SELECT SUBSTRING(TEXT, r.statement_start_offset / 2, CASE
WHEN r.statement_end_offset …Run Code Online (Sandbox Code Playgroud)