我正在将数据库恢复到事务和合并复制的每一端。基本上,发布者和订阅者最初是同一个数据库。
我仍然需要运行快照代理才能开始工作。
我的意思是,如何在不运行 bcp 命令的情况下运行快照,而不复制数据?
不过,我同意复制数据结构。
我正在将数据库恢复到事务和合并复制的每一端。基本上,发布者和订阅者最初是同一个数据库。
我仍然需要运行快照代理才能开始工作。
我的意思是,如何在不运行 bcp 命令的情况下运行快照,而不复制数据?
不过,我同意复制数据结构。
如何找到我实际可以连接的数据库列表?
我正在使用sys.master_files检查数据库文件的状态,但是,在辅助数据库上,数据库正在同步并且显示为在线
我不能做到这一点:
use my_database
我不能这样做:
select * from my_database.sys.master_files
消息 976,级别 14,状态 1,第 364 行 目标数据库“my_database”正在参与可用性组,当前无法访问查询。数据移动已暂停,或者可用性副本未启用读取访问。要允许对此数据库和可用性组中的其他数据库进行只读访问,请启用对该组中的一个或多个辅助可用性副本的读取访问权限。有关详细信息,请参阅 SQL Server 联机丛书中的 ALTER AVAILABILITY GROUP 语句。
我正在使用sqlwatch来监视我的一些服务器,它有一个从名为 的表中批量删除的作业dbo.sqlwatch_logger_snapshot_header
我遇到了很多锁定和阻塞问题,因为该表由不同的进程使用,然后我禁用了所有其他作业,但处理该表的作业除外。
我使用以下脚本禁用所有其他 sqlwatch 作业:
use distribution
set nocount on
set transaction isolation level read uncommitted
declare @Job_id uniqueidentifier
declare @job_name varchar(300)
declare @category_name varchar(300)
declare @body varchar(max)
declare @flag tinyint
declare @enabled bit = 0; --0 - disable 1-enable
declare @subject varchar(300) = case when @enabled = 0 then 'Disabling sqlwatch jobs on' + @@servername else 'Enabling sqlwatch jobs on' + @@servername end;
declare @job_enabled bit;
set @flag = 0
set @body = 'The following jobs are going to be ' +
case when @enabled = 0 then 'Disabled' else 'Enabled' end
+ ' : '+char(10)+Char(13)
IF OBJECT_ID('tempdb.[dbo].[#LogReaderAgents]') IS NOT NULL
DROP TABLE [dbo].[#LogReaderAgents]
CREATE TABLE [dbo].[#LogReaderAgents] (
[job_id] UNIQUEIDENTIFIER NOT NULL,
[job_name] SYSNAME NOT NULL,
[category_name] SYSNAME NOT NULL,
[enabled] TINYINT NOT NULL)
INSERT INTO [dbo].[#LogReaderAgents] ([job_id],[job_name],[category_name],[enabled])
select job_id, job_name = sj.name, category_name=sc.name, sj.enabled
from msdb.dbo.sysjobs sj
inner join msdb.dbo.syscategories sc
on sj.category_id = sc.category_id
where 1=1
and sj.name like 'SQLWATCH%'
-- and sc.category_id in (10,13)
and sj.name not in ('SQLWATCH-INTERNAL-RETENTION')
-- exec sp_gettabledef 'dbo.#LogReaderAgents'
-- exec sp_GetInsertList 'TEMPDB','DBO.#LogReaderAgents'
DECLARE c1 CURSOR FOR
SELECT Job_id,job_name, category_name, [enabled]
FROM #LogReaderAgents
OPEN c1
FETCH NEXT FROM c1
INTO @Job_id,@job_name,@category_name,@job_enabled
WHILE @@FETCH_STATUS = 0
begin
if (select top (1) stop_execution_date from msdb.dbo.sysjobactivity ja
where Job_ID = @Job_id
and
ja.start_execution_date IS NOT NULL
order by Start_execution_date desc) is not NULL
begin
set @flag = 1
Print @job_name +' is ' + case when @job_enabled=1 then 'Enabled' else 'disabled' end
exec msdb..sp_update_job @job_id = @job_id, @enabled = @enabled
set @Body = @Body + char(10)+char(13) + @job_name + ' -- ' + @category_name +' is ' + case when @job_enabled=1 then 'Enabled' else 'disabled' end
end
FETCH NEXT FROM c1
INTO @Job_id,@job_name,@category_name,@job_enabled
end
CLOSE c1
DEALLOCATE c1
但是,此后作业仍在运行,但我没有看到该表中的记录数量有任何变化。
这是执行过程并批量删除的作业:
现在有3690万
所以基本上它正在工作,所以一切都很好。
现在我的问题是:
假设我因任何原因不得不停止这份工作
这是批量删除,如果我现在必须停止这项工作,有多少行受到影响,回滚尚未提交的内容的成本有多大?
通常,当数据库在线时,我使用以下查询并获取每个文件内有多少可用空间:
SELECT CONVERT (decimal(12,2) ,
(CONVERT(decimal(12,2), size)/128)/1024.00)
- CONVERT(decimal(12,2),
ROUND(fileproperty(a.name,'SpaceUsed')/128.000,2)/1024.00) as [FREESPACE GB],
*
FROM sys.database_files a WITH(NOLOCK)
您需要位于要查看的数据库中。
但是,当数据库离线时如何做到这一点呢?
我还没有找到办法。
我正在尝试这个,但没有成功:
select object_name,counter_name,instance_name,cntr_value,
case cntr_type
when 65792 then 'Absolute Meaning'
when 65536 then 'Absolute Meaning'
when 272696576 then 'Per Second counter and is Cumulative in Nature'
when 1073874176 then 'Bulk Counter. To get correct value, this value needs to be divided by Base Counter value'
when 537003264 then 'Bulk Counter. To get correct value, this value needs to be divided by Base Counter value'
else 'I don"t know'
end as counter_comments
from sys.dm_os_performance_counters with(nolock)
where cntr_type not in (1073939712)
and counter_name in ('Data File(s) Size (KB) ',
'Database pages ')
有没有办法找出脱机数据库文件内的可用空间?
我有一个查询,显示 sql server 使用了多少内存,最大内存和最小内存、cpu 等设置。
这是查询:
--============================================================
--checking current memory settings and usage
--marcelo miorelli
--16-feb-2014
--============================================================
SELECT R.[instance],
R.[Logical CPU Count],
R. [Hyperthread Ratio],
R.[Physical CPU Count],
R.[Physical Memory (GB)],
k.[Max server memory (GB)],
FOO.Memory_usedby_Sqlserver_MB,
FOO.Locked_pages_used_Sqlserver_MB,
k.[Min server memory (GB)],
k.[optimize for ad hoc workloads],
R.affinity_type_desc,
FOO.process_physical_memory_low,
FOO.process_virtual_memory_low,
R.virtual_machine_type_desc,
R.sqlserver_start_time
FROM (
SELECT [instance]=@@servername,
cpu_count AS [Logical CPU Count],
hyperthread_ratio AS [Hyperthread Ratio],
cpu_count/hyperthread_ratio AS [Physical CPU Count],
CONVERT(decimal(12,2),physical_memory_kb/1024.00/1024.00) AS [Physical Memory (GB)],
affinity_type_desc,
virtual_machine_type_desc,
sqlserver_start_time
FROM sys.dm_os_sys_info WITH (NOLOCK)
) R
INNER JOIN (
SELECT [instance] = @@servername,
[Max server memory (GB)] = CONVERT(decimal(12,2),CAST(p.[max server memory (MB)] AS DECIMAL(12,2))/1024.00),
[Min server memory (GB)] = CONVERT(decimal(12,2),CAST(P.[min server memory (MB)] AS DECIMAL(12,2))/1024.00),
[min memory per query (MB)]= CONVERT(decimal(12,2),CAST(P.[min memory per query (KB)] AS DECIMAL(12,2))/1024.00),
p.[optimize for ad hoc workloads]
FROM ( SELECT name, [value_in_use]
FROM sys.configurations) t
PIVOT (MAX([value_in_use])
FOR name IN (
[min server memory (MB)],
[min memory per query (KB)],
[max server memory (MB)],
[optimize for ad hoc workloads]
)) p
) K
ON R.instance = K.instance
INNER JOIN (
SELECT [instance] = @@servername,
CONVERT(decimal(12,2),CAST(physical_memory_in_use_kb AS DECIMAL(12,2))/1024.00) AS Memory_usedby_Sqlserver_MB,
CONVERT(decimal(12,2),CAST(locked_page_allocations_kb AS DECIMAL(12,2))/1024.00) AS Locked_pages_used_Sqlserver_MB,
CONVERT(decimal(18,2),CAST(total_virtual_address_space_kb AS DECIMAL(18,2))/1024.00/1024.00) AS Total_VAS_in_GB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory t
) FOO
ON R.instance = foo.instance
OPTION (RECOMPILE);
这个查询给了我这个 - 目前在一个不繁忙的开发服务器上:
physical_memory_in_use_kb
我的问题与locked_page_allocations_kb
dmv相关sys.dm_os_process_memory
。
我如何找到该内存中保存的对象或任何 sql server?
我可以看到,在我的例子中,最小内存设置为 2 Gb,但使用的内存超过 5 Gb。
可能我实际上不需要知道,因为目前可能没有内存压力,但仍然有办法找出 sql server 在内存中保存了什么?
在将 1.8 TB 大型数据库恢复到另一台服务器时,当恢复完成大约 90% 时,我遇到了此错误消息:
90%已处理完毕。
消息 3013,级别 16,状态 1,第 52 行
RESTORE DATABASE 异常终止。
消息 1204,级别 19,状态 4,第 52 行
SQL Server 数据库引擎实例此时无法获取 LOCK 资源。当活跃用户较少时重新运行您的语句。要求数据库管理员检查该实例的锁和内存配置,或者检查长时间运行的事务。
SELECT [instance]=@@servername,[setting name]=name, value, value_in_use, [description]
FROM sys.configurations
where name in ('min server memory (MB)',
'min memory per query (KB)',
'max server memory (MB)',
'optimize for ad hoc workloads')
SELECT [instance]=@@servername,
cpu_count AS [Logical CPU Count],
hyperthread_ratio AS [Hyperthread Ratio],
cpu_count/hyperthread_ratio AS [Physical CPU Count],
CONVERT(decimal(12,2),physical_memory_kb/1024.00/1024.00) AS [Physical Memory (GB)],
affinity_type_desc,
virtual_machine_type_desc,
sqlserver_start_time
FROM sys.dm_os_sys_info WITH (NOLOCK)
用它来检查sql错误日志,我找不到任何明确的迹象表明上述原因。
EXEC xp_readerrorlog 1
这是我发现的:
Using dynamic lock allocation. Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node. This is an informational message only. No user action is required.
Node configuration: node 0: CPU mask: 0x000000000000000f:0 Active CPU mask: 0x000000000000000f:0. This message provides a description of the NUMA configuration for this computer. This is an informational message only. No user action is required.
怎样做才能让我的恢复彻底进行而不是中途停止?
我刚刚要求基础设施向 sql server 盒子添加内存,现在总内存为 16Gb
我已将sql server中的最大内存设置为12GB。
当我运行下面的内存查询时:
SELECT [ServerName]=@@servername,
[Setting Name]=name,
value,
value_in_use,
[Value (GB)]=CONVERT(decimal(12,2),CONVERT(decimal(12,2), value_in_use)/1024.00),
[description]
FROM master.sys.configurations with(nolock)
WHERE name like '%server memory%'
ORDER BY name OPTION (RECOMPILE);
--Msg 260, Level 16, State 3, Line 12
--Disallowed implicit conversion from data type sql_variant to data type numeric,
--table 'master.sys.configurations', column 'value_in_use'.
--Use the CONVERT function to run this query.
SELECT
CONVERT(decimal(12,2),physical_memory_in_use_kb/1024.00/1024.00 ) AS sql_physical_memory_in_use_GB,
CONVERT(decimal(12,2),large_page_allocations_kb/1024.00/1024.00) AS sql_large_page_allocations_GB,
CONVERT(decimal(12,2),locked_page_allocations_kb/1024.00/1024.00) AS sql_locked_page_allocations_GB,
CONVERT(decimal(12,2),virtual_address_space_reserved_kb/1024.00/1024.00) AS sql_VAS_reserved_GB,
CONVERT(decimal(12,2),virtual_address_space_committed_kb/1024.00/1024.00) AS sql_VAS_committed_GB,
CONVERT(decimal(12,2),virtual_address_space_available_kb/1024.00/1024.00) AS sql_VAS_available_GB,
REPLACE(CONVERT(VARCHAR(50),CAST(page_fault_count AS MONEY),1), '.00','') AS page_fault_count,
memory_utilization_percentage AS sql_memory_utilization_percentage,
CASE WHEN process_physical_memory_low = 1 THEN 'Yes' ELSE 'No' END AS sql_process_physical_memory_low,
CASE WHEN process_virtual_memory_low = 1 THEN 'Yes' ELSE 'No' END AS sql_process_virtual_memory_low
FROM sys.dm_os_process_memory;
SELECT CONVERT(decimal(12,2),committed_kb/1024.00/1024.00 ) AS [SQL Server Committed Memory in GB],
CONVERT(decimal(12,2),committed_target_kb/1024.00/1024.00 ) AS [SQL Server Target Committed Memory in GB],
CONVERT(decimal(12,2),physical_memory_kb/1024.00/1024.00 ) AS [Server Physical Memory in GB],
sql_memory_model_desc
FROM sys.dm_os_sys_info;
我明白了:
问题:
为什么sql server内存不是12GB?
我刚刚恢复了一个数据库,但后来我注意到 create_date 仍然是恢复前的日期。
有没有办法可以将 create_date 更改为新数据库(恢复后)?
这是脚本:
USE [master]
RESTORE DATABASE [SUPT_S01_Radhe]
FROM DISK = N'\\krishna3.radhe.co.uk\support\MM_Backups\S01__JagannathaeCA_12122023.bak'
WITH FILE = 1,
MOVE N'radhe_Data' TO N'Y:\DATA\SUPT_S01_radhe_shyam_Data.mdf',
MOVE N'radhe_ChangeLog' TO N'W\:\DATA\SUPT_S01_radhe_shyam_ChangeLog.ndf',
MOVE N'radhe_Docs' TO N'Z:\DATA\SUPT_S01_radhe_shyame_Docs.ndf',
MOVE N'radhe_Log' TO N'P:\LOGS\SUPT_S01_radhe_shyam_Log.ldf',
NOUNLOAD, REPLACE, STATS = 1
select name, database_id, create_date from sys.databases d
where d.database_id in (1,2,3,4,8)
我有一个无法杀死的顽固 spid,它阻止了我的 tempdb的事务日志被截断
这就是我发现这个流氓 spid 的方法:
if object_id('tempdb..#OpenTranStatus','U') is not null
drop table #OpenTranStatus
CREATE TABLE #OpenTranStatus (
ActiveTransaction varchar(25),
Details sql_variant
);
-- Execute the command, putting the results in the table.
INSERT INTO #OpenTranStatus
EXEC ('DBCC OPENTRAN (sqlwatch) with tableresults')
SELECT * FROM #OpenTranStatus
这是它正在运行(或保留)的查询:
select d.database_id , sd.sqlwatch_database_id, sd.sql_instance
into #d
from dbo.vw_sqlwatch_sys_databases d
inner join [dbo].[sqlwatch_meta_database] sd
on sd.[database_name] = d.[name] collate database_default
and sd.[database_create_date] = case when d.name = 'tempdb' then '1970-01-01 00:00:00.000' else d.[create_date] end
and sd.sql_instance = @sql_instance
left join [dbo].[sqlwatch_config_exclude_database] ed
on d.[name] like ed.database_name_pattern collate database_default
and ed.snapshot_type_id = @snapshot_type_id
where ed.snapshot_type_id is null
option (keep plan)
它已经运行了60 多个小时:
它已经被杀死了。
所以我尝试做的事情:
alter database sqlwatch set single_user with rollback immediate
但没用
kill 54 with statusonly
SPID 54:正在进行事务回滚。预计回滚完成:0%。预计剩余时间:0 秒。
问题:
我怎样才能停止spid54?
我正在恢复一个数据库,这个数据库非常大,它有 6 个备份文件(意味着备份被分成 6 个较小的文件)我可以使用恢复标签看到指示
MediaFamilyId uniqueidentifier 媒体系列的唯一标识号。
MediaSequenceNumber int 该媒体在媒体系列中的序列号。
这是恢复命令:
restore filelistonly
FROM DISK = '\\MY_BACKUP_SERVER\SQLBackups\MY_SERVER\MY_DATABASE\FULL\MY_SERVER_MY_DATABASE_FULL_20231215_180002_6.bak'
restore labelonly
FROM DISK = '\\MY_BACKUP_SERVER\SQLBackups\MY_SERVER\MY_DATABASE\FULL\MY_SERVER_MY_DATABASE_FULL_20231215_180002_6.bak'
restore headeronly
FROM DISK = '\\MY_BACKUP_SERVER\SQLBackups\MY_SERVER\MY_DATABASE\FULL\MY_SERVER_MY_DATABASE_FULL_20231215_180002_6.bak'
我的问题是,如何在 msdb 中找到(在本例中为 6 个)文件?
基本上是一个查询来获取这 6 个文件 - 最后的完整备份 - 恢复这 (6) 个文件。
这是与下面的查询非常相似的查询的执行计划,它给了我错误消息:
消息 6335,级别 16,状态 102,第 43 行 XML 数据类型实例的嵌套节点级别过多。允许的最大深度为 128 层。
SELECT *, cast(plantext as xml)
FROM [my_Safer_database].[dbo].[PS_PlanHistory]
where servername='IR1SH_server_SQL0014P0'
and procname='ManageInPlayEvents'
order by cachedtime desc
上表的定义是:
我知道问题与转换为 xml 有关,我该如何修复它或解决它?
预期结果示例:
我最终使用下面的脚本将一些数据库移动到兼容级别 150
USE [master]
GO
ALTER DATABASE [DB1] SET COMPATIBILITY_LEVEL = 150
GO
USE [DB1]
GO
ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = ON;
ALTER DATABASE SCOPED CONFIGURATION SET INTERLEAVED_EXECUTION_TVF = OFF;
ALTER DATABASE SCOPED CONFIGURATION SET DEFERRED_COMPILATION_TV = OFF;
ALTER DATABASE SCOPED CONFIGURATION SET BATCH_MODE_ON_ROWSTORE = OFF;'
我想为此脚本创建一个回滚,但我如何才能找到当前值LEGACY_CARDINALITY_ESTIMATION
和其他设置?
我知道使用OPTION(QUERYTRACEON 9481 /*force legacy CE*/)
或拥有跟踪标志 9481 会强制执行该行为。
当我需要重命名一个表并因此重命名它的主键(以及所有其他约束)时,我使用以下简单的示例脚本:
if object_id('dbo.Radhe1',N'U') is not null
drop table dbo.radhe1
create table dbo.Radhe1 (
id int identity(-1008,-1) not null,
name nvarchar(50) null
, constraint pk_Radhe1 primary key clustered (Id)
);
insert into dbo.Radhe1(name)values('Krishna')
go 1008
select count(*) from dbo.radhe1
exec sp_rename N'dbo.Radhe1.pk_Radhe1', N'pk__Radhe_to_be_removed';
exec sp_rename N'dbo.Radhe1', N'Radhe1_to_be_removed'
select count(*) from dbo.Radhe1_to_be_removed
我所看到的是,当我的表超过一百万行或任何大小时,或者服务器很忙时,人们倾向于重命名表,然后删除并重新创建主键,据我所知工作量很大,资源非常紧张。
例如(与前面示例无关的名称):
/* rename existing tables */
EXEC sp_rename 'dbo.DocumentDetailSearchTags', 'dbo.DocumentDetailSearchTags_TOBEDROPPED'
EXEC sp_rename 'dbo.SearchTags', 'dbo.SearchTags_TOBEDROPPED'
/* update pk constraint names */
ALTER TABLE dbo.DocumentDetailSearchTags_TOBEDROPPED
DROP CONSTRAINT PK_DocumentDetailSearchTags
ALTER TABLE dbo.DocumentDetailSearchTags_TOBEDROPPED
ADD CONSTRAINT PK_DocumentDetailSearchTags_TOBEDROPPED PRIMARY KEY CLUSTERED
(
[documentDetailId] ASC,
[searchTagId] ASC
)
现在我不知道 sp_rename 在幕后做了什么,我还没有机会在繁忙的实时服务器上测试它。
问题是:
在繁忙的实时服务器上,sp_rename
重命名表的主键会比alter table drop and add constraint
?
我正在使用dbcc show_statistics在我的直方图中寻找倾斜数据并提高我的统计质量。
OPTIMIZE FOR UNKNOWN不使用值 - 相反,它使用密度向量。
如果您运行DBCC SHOWSTATISTICS ,则它是第二个结果集的“所有 密度”列中列出的值。
在下图中,由于数据倾斜,估计的行数与实际的行数存在差异。
这谈到了 @variables 和recompile,它们可以提供帮助并且是解决方案的一部分。
问题:
如何在缓存的执行计划中找到估计行数与实际行数有差异的查询?
我知道无法在 sql server 中为会话设置排序规则。
我有不同的服务器具有不同的排序规则,但是,其中一个是区分大小写的排序规则,如下图所示,在细节上可能会更加严格。
是否有任何设置或任何我可以做的事情来开发我的脚本,就好像排序规则是区分大小写的一样,所以当我需要将脚本移植到区分大小写的服务器时,一切都已经好了?
我一直在寻找在不改变任何东西的情况下操纵排序规则,试图将其限制在我的会话中,可以这么说,但我找不到任何东西,有什么我能做的吗?
set transaction isolation level read uncommitted
set nocount on
set deadlock_priority low
use ReportServer
--select * from sys.tables
select top 10 Name, Path, CreationDate
from dbo.catalog
order by path COLLATE Latin1_General_100_CI_AS_KS_WS desc
exec sp_help 'dbo.catalog'
DECLARE @SQL nvarchar(max)
SET @SQL='use ReportServer;select top 10 Name,
Path, CreationDate from dbo.Catalog order by path '
SET @SQL=@SQL + 'COLLATE Latin1_General_BIN DESC'
PRINT @SQL
EXEC sp_executesql @SQL
SET @SQL='use ReportServer;select top 10 Name, Path,
CreationDate from dbo.Catalog order by path '
SET @SQL=@SQL + 'COLLATE SQL_Latin1_General_CP1250_CS_AS DESC'
PRINT @SQL
EXEC sp_executesql @SQL
use master
go
SELECT name, COLLATIONPROPERTY(name, 'CodePage') AS Code_Page, description
FROM sys.fn_helpcollations()
ORDER BY name;
有些程序可以手动运行但不能在作业中运行,或者在从应用程序运行时失败,或者在 SSIS SQL 任务中无法运行。
我的工作在所有会话中,但一个。
这是我正在运行的代码 - 它调用一个存储过程,该过程获取触发器定义并将其保存在临时表中。
工作正常,这是我自动化工作的一部分。
IF OBJECT_ID('tempdb.dbo.#Jagannatha_sp_getTriggerDef') IS NOT NULL
DROP TABLE #Jagannatha_sp_getTriggerDef
CREATE TABLE #Jagannatha_sp_getTriggerDef (
DB sysname not null,
parent_name nvarchar(600) not null,
object_id int not null,
trigger_name sysname not null,
is_disabled bit,
i int not null,
[trigger_definition] NVARCHAR(MAX) not null,
primary key clustered (DB,trigger_name,i))
truncate table #Jagannatha_sp_getTriggerDef
exec sp_getTriggerDef @dbname = 'APCore',
@TableName = 'dbo.receivedLog',
@Drop_ONly = 0,
@Radhe = '#Jagannatha_sp_getTriggerDef'
SELECT *
FROM #Jagannatha_sp_getTriggerDef
order by db,i
我在没有触发器的表上运行它 - 只是为了让它尽可能简单
它带有警告
IF 'my_server\_DEVELOPMENT' <> @@ServerName THROW 50001, 'Wrong Server!!!',1
都好。
但是在这个特定的会话中:
到目前为止,我可以发现本次会议没有什么不同。
SELECT *
FROM sys.dm_exec_sessions
where login_name = 'my_company\my_user'
and session_id = @@SPID
第二个是失败的地方。所有其他它工作正常。
我该怎么做才能找出不同之处?甚至更好的是,更改程序以便尽管存在差异,但它仍然可以工作?
我正在查询列出当前正在执行的请求中存在的键查找,我基本上想解决这个问题,看看我是否可以从执行计划中消除这些键查找。
要获取这些键查找,我使用以下查询:
SELECT
er.session_id,
er.blocking_session_id,
er.start_time,
er.status,
dbName = DB_NAME(er.database_id),
er.wait_type,
er.wait_time,
er.last_wait_type,
er.granted_query_memory,
er.reads,
er.logical_reads,
er.writes,
er.row_count,
er.total_elapsed_time,
er.cpu_time,
er.open_transaction_count,
er.open_transaction_count,
s.text,
qp.query_plan,
logDate = CONVERT(DATETIME,GETDATE()),
logTime = CONVERT(DATETIME,GETDATE())
FROM sys.dm_exec_requests er
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) s
CROSS APPLY sys.dm_exec_query_plan(er.plan_handle) qp
WHERe er.session_id <> @@SPID
and CONVERT(VARCHAR(MAX), qp.query_plan) LIKE '%IndexScan Lookup%'
这个查询我面临的问题是它返回 anykey lookup
而不管它的成本。
我想过滤那些,我只想看到昂贵的键查找。
如何过滤我的查询以仅显示昂贵的查找操作?
我有以下查询:
SELECT u.userId,
app.applicationId
FROM app.application AS app
INNER JOIN app.applicant AS ap
ON ap.applicantId = app.applicantId
INNER JOIN usr.[user] AS u
ON u.userId = ap.userId
LEFT JOIN msg.emailTemplateSent AS t
ON t.toUserId = u.userId
AND t.emailTemplateName = 'v4_before_sixWeek_latestFlight_reminder'
WHERE Convert(Date, GETUTCDATE()) =
DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
AND t.emailEventId IS NULL
ORDER BY app.applicationId ASC
请再次注意 where 子句的第一行:
Convert(Date, GETUTCDATE()) = DATEADD(week,-6,Convert(Date, app.flightDateLatest ))
我可以用我的索引可以使用的方式来改变它吗?索引实际上被使用,但它是一个完整的扫描。
也可以在这里看到:
这是我的索引定义:
USE [APCore];
CREATE NONCLUSTERED INDEX i_flightDateLatest
ON [app].[application] ( flightDateLatest ASC )
INCLUDE ( [applicantId] , [applicationId] , [programID])
WITH ( PAD_INDEX = OFF,
FILLFACTOR = 100 ,
SORT_IN_TEMPDB = OFF ,
ONLINE = OFF,
--DROP_EXISTING = ON,
IGNORE_DUP_KEY = OFF,
STATISTICS_NORECOMPUTE = OFF,
DATA_COMPRESSION=PAGE,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON )
ON [NONCLUSTERED_INDEXES]
不幸的是,我无法更改flightDateLatest
从日期时间调用的列以避免转换
除了创建计算列或更改架构之外,在这种情况下还有什么办法可以避免读取全表\索引扫描?
更新:
接受答案后,相应地更改查询,现在索引用于查找操作,如下图所示。
请注意原始查询的 94% 成本与 6% 改进查询的成本: