小编The*_*war的帖子

哈希键探测和残差

比如说,我们有一个这样的查询:

select a.*,b.*
from 
a join b
on a.col1=b.col1
and len(a.col1)=10
Run Code Online (Sandbox Code Playgroud)

假设上述查询使用 Hash Join 并具有残差,则探测键将为col1,残差将为len(a.col1)=10

但是在查看另一个示例时,我可以看到探针和残差是同一列。以下是对我想说的内容的详细说明:

询问:

select *
from T1 join T2 on T1.a = T2.a 
Run Code Online (Sandbox Code Playgroud)

执行计划,突出显示探测和残差:

在此处输入图片说明

测试数据:

create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))

set nocount on
declare @i int
set @i = 0
while @i < 1000
  begin
      insert T1 values (@i * 2, @i * 5, @i)
    set @i = @i …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan database-internals query-performance

21
推荐指数
1
解决办法
4255
查看次数

在 IF EXISTS 中包装查询使其非常慢

我有以下查询:

select databasename 
from somedb.dbo.bigtable l where databasename ='someval' and source  <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
Run Code Online (Sandbox Code Playgroud)

上述查询在三秒内完成。

如果上面的查询返回任何值,我们希望存储过程退出,因此我将其重写如下:

If Exists(
select databasename 
from somedb.dbo.bigtable l where databasename ='someval' and source  <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
Run Code Online (Sandbox Code Playgroud)

但是,这需要 10 分钟。

我可以像下面这样重写上面的查询,它也可以在不到 3 秒的时间内完成:

  select databasename 
from somedb.dbo.bigtable l where databasename ='someval' and source  <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0 …
Run Code Online (Sandbox Code Playgroud)

performance sql-server sql-server-2012 exists query-performance

17
推荐指数
1
解决办法
8864
查看次数

如何回答为什么突然需要更改索引或查询

我是初级 DBA,有 3 年的经验。我们的工作是微调查询或建议开发人员应该重写特定代码或需要索引。

开发团队经常问的一个简单问题是:“昨天运行良好,突然发生了什么变化?” 我们将被要求检查基础设施方面。对任何问题的第一反应似乎总是将最大的责任归咎于基础设施,这始终是首先要验证的事情。

我们应该如何回答开发团队提出的“改变了什么”的问题?大家有遇到过同样的情况吗?如果是这样,请分享您的经验。

performance sql-server execution-plan

11
推荐指数
3
解决办法
879
查看次数

SQLServer 中的 BMK 运算符是什么

我试图回答这个问题,说明 from 子句是可选的。

在此处输入图片说明

如您所见,查询计划中有 BMK 运算符,但没有指示显示它是如何计算的。

到目前为止
尝试过的步骤:我开始使用 BMK1000 进行搜索,但它显示了一堆使用相同运算符的问题。最后我找到了一个线程,上面写着“您所引用的 BMK 是堆中的存储位置,被保留使用非聚集索引而不是簇键。”..但不确定这与我有什么关系,因为我没有任何索引..

问:
什么是 BMK 运算符以及它是如何计算的。任何指针也会有所帮助

这是重现问题的SQLFiddle

sql-server execution-plan operator

9
推荐指数
1
解决办法
2482
查看次数

为嵌套循环设置统计 I/O

考虑以下查询:

CREATE PROC dbo.GetPage  @orderid  AS INT    = 0, -- anchor sort key
            @pagesize AS BIGINT = 25
 AS
SELECT
TOP (@pagesize) orderid, orderdate, custid, empid
 FROM dbo.Orders WHERE orderid > @orderid ORDER BY orderid;

exec GetPage 25,25
Run Code Online (Sandbox Code Playgroud)

上述查询的 SET STATISTICS IO 返回:

(25 row(s) affected)
Table 'Orders'. Scan count 1, logical reads 87, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)

Itzik Ben-Gan 在他的书中对上述内容的解释是这样的:

执行查询计划所涉及的 I/O 成本由以下组成:

  • 查找索引的叶子:3 次读取(索引具有三个级别)。 …

sql-server execution-plan database-internals sql-server-2016

8
推荐指数
1
解决办法
950
查看次数

由于 log_backup,事务日志已满

我正在测试如何在不同的恢复模式下记录某些操作。以下是我到目前为止所做的步骤

1.在完全恢复模式下
创建数据库2.进行备份
3.创建一个表并插入 1000 万条记录
4.进行日志备份,检查 VLF 计数并查看日志空间可用百分比
5.现在进行索引重建并查看使用生成的记录fn_dblog 函数

6.现在我切换到批量恢复模型
7.进行了备份
8.进行了日志备份
9.进行了索引重建

奇怪的是,索引重建失败并出现以下错误。

该语句已终止。消息 9002,级别 17,状态 2,第 1 行 由于“LOG_BACKUP”,数据库“bulklogging”的事务日志已满。

那不是真的,实际上

1.日志空间自动增长不受限制

自增长设置

2.存储日志文件的空间

存储日志文件的驱动器上的空间

有人可以帮助我理解为什么我会遇到错误,即使有空间并且没有限制自动增长

添加索引大小的图像..

问题已解决,但不确定此更改有何不同。任何指针将不胜感激..

评论说两个长——所以在这里发帖......

我再次编写了索引,在更改恢复模型之后它起作用了。而且之前和之后的脚本索引完全保持不变,只有会话发生了变化。但我不确定这是如何工作的。

前 :

USE [bulklogging]  
GO  
ALTER INDEX [PK__bcc__3213E83FAC9DB5ED] ON [dbo].[bcc] 
REBUILD PARTITION = ALL WITH (PAD_INDEX = OFF, 
STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
Run Code Online (Sandbox Code Playgroud)

后:

USE [bulklogging]  
GO  
ALTER INDEX [PK__bcc__3213E83FAC9DB5ED] ON [dbo].[bcc] 
REBUILD PARTITION = ALL WITH (PAD_INDEX …
Run Code Online (Sandbox Code Playgroud)

sql-server transaction-log

7
推荐指数
1
解决办法
10万
查看次数

将 .Bak 文件还原到不同的服务器

我将一些数据库备份从一台服务器复制到另一台服务器(新实例不存在数据库)。我尝试使用以下命令进行恢复

Restore database dbname
from disk='g:\e2bak\dbname.bak'
with 
stats=10
Run Code Online (Sandbox Code Playgroud)

它因以下错误而失败

文件“G:\MSSQL$s73g\MDF\dbname.mdf”的目录查找失败,出现操作系统错误 3(系统找不到指定的路径。)消息 3156,级别 16,状态 3,第 1 行

服务器级别的默认数据库设置也是存储数据和登录

G:\MSSQL10_50.SG\MSSQL
Run Code Online (Sandbox Code Playgroud)

我可以通过指定移动选项来克服错误。但我的困惑是

1.Why database .bak file is looking for G:\MSSQL$s73g\MDF\dbname.mdf",this is the path
  of dbname database files in production from where we copied the .bak file

2.Also when I restored the database with move option and took a backup in same server,
  I was able to restore the Database with below command

Restore database dbname 
from disk='G:\e1ebk\dbname.bak'
with replace,stats=10
Run Code Online (Sandbox Code Playgroud)

你能帮我理解为什么 .Bak 文件位置指向某个其他目录(它甚至不存在于我们的服务器中,只存在于生产服务器上),以及在第二种情况下为什么这在没有移动选项的情况下有效。

sql-server backup

6
推荐指数
1
解决办法
2万
查看次数

SQL Server 线程状态

我们的 SQL 配置为最多使用 704 个线程,有时我们会收到警告,指出只剩下 10 个线程,所以我无法理解 SQL 是否保持线程打开,因为再次创建新线程的成本很高。

所以我的问题是

  1. 如何知道线程是否可用于新请求或当前正忙于其他请求。

  2. 我正在尝试task_address从 sys.dm_exec_requests 与 sys.dm_os_tasks链接,worker_address如下所示

    select * from sys.dm_exec_requests ec
    join
    sys.dm_os_tasks tsk
    on tsk.task_state=ec.task_address
    join
    sys.dm_os_workers wrk
    on wrk.worker_address=tsk.worker_address
    
    Run Code Online (Sandbox Code Playgroud)

我没有看到任何输出,这是否意味着我可以假设所有线程都是空闲的

  1. 目前下面是我的工作线程的状态,这个挂起是什么意思?我可以看到计数超过 500 的挂起状态。我没有看到任何阻塞

在此处输入图片说明

4.我可以使用下面的查询来发现我有工作线程饥饿吗

select status from sys.dm_Exec_requests
Run Code Online (Sandbox Code Playgroud)

如果状态为挂起,我可以假设 SQL 正在等待新的工作线程

  1. 目前我看到一个会话,在 sysprocesses 中有超过 250 行,当我查询时sys.dm_os_Waiting_tasks,我可以看到超过 2186 行,其中 90% 是针对同一个会话。所以我的问题是查询如何跨越这么多线程

在此处输入图片说明

  1. 我会使用下面的查询获得可用的工人数量,这是正确的吗?

    select (
            select max_workers_count
            from sys.dm_os_sys_info
            ) - (
            select sum(active_workers_count)
            from sys.dm_os_Schedulers
            )
    
    Run Code Online (Sandbox Code Playgroud)

sql-server

6
推荐指数
1
解决办法
2万
查看次数

理解下面的执行计划

我有两个表 tb1 和 tb2,tb1 上没有任何索引。我在 tb1 中填充了 1000000 行,tb2 中有 500 行,并且在 ID 列上有一个聚集索引。

为了理解嵌套循环连接,我使用了以下查询:

SELECT * 
FROM tb1
INNER JOIN tb2 ON tb1.id=tb2.id 
OPTION(loop join);
Run Code Online (Sandbox Code Playgroud)

我得到了以下执行计划:

在此处输入图片说明

没有索引的 Tb1 被扫描,成本为 2%,而索引正在 tb2 上使用,成本为 98%。

在此处输入图片说明

我的问题是:

  1. 如何理解以上剪辑显示的估计操作员成本 (138.236)

在此处输入图片说明

  1. 从上面的表扫描片段(其成本为 2%)来看,执行次数是 24,这是否意味着 sql 批量读取存储在内存中的行,并对每一行从 tbl2 执行查找操作?

有人可以向我解释执行计划以及任何指针以了解有关强制扫描的更多信息,单击运算符后按 F4 时强制索引。

sql-server execution-plan

5
推荐指数
1
解决办法
715
查看次数

SQLAZURE 资源限制 - 最大并发会话数

我试图为我们的内部消耗选择一个层,并详细了解此限制。Azure SQL 数据库资源限制

一个特殊的问题实例如下图所示,并特别突出显示了值

在此输入图像描述

正如您所看到的,从突出显示的内容来看,最大并发限制为 60 个并发登录和 600 个并发会话

问:
单个查询可以并行进行,并且可以有多个会话,这些会话会在此限制下计数吗?

我尝试使用 Paul White 的文章强制并行查询执行计划来测试这一点,如下所示

DBCC FREEPROCCACHE
DBCC SETCPUWEIGHT(1000)

GO
-- Query to test  
some expensive query
GO

DBCC SETCPUWEIGHT(1)  
DBCC FREEPROCCACHE   
Run Code Online (Sandbox Code Playgroud)

或使用

OPTION (RECOMPILE, QUERYTRACEON 8649)
Run Code Online (Sandbox Code Playgroud)

但当我使用下面的 DMV 检查时,我最多只能进行 9 个会话

select * from sys.dm_os_tasks 
where session_id=61
Run Code Online (Sandbox Code Playgroud)

这些跟踪标志和 DBCC 选项在 azure 中不起作用。如果我不清楚,请告诉我

sql-server azure-sql-database

5
推荐指数
1
解决办法
1742
查看次数