SQL Server 优化器特性导致的内存授予相关BUG

原文:SQL Server 优化器特性导致的内存授予相关BUG

我们有时会遇到一些坑,要不填平,要不绕过.这里为大家介绍一个相关SQL Server优化器方面的特性导致内存授予的相关BUG,及相关解决方式,也顺便回答下邹建同学的相关疑问.

问题描述

一个简单的查询消耗了匪夷所思的内存.(邹建同学发现的)

原文链接

Code

create table test_mem
(
id int identity(1,1) primary key,
itemid int not null,
date datetime not null,
str1 varchar(max) null
)

INSERT test_mem( itemid,date )
    SELECT TOP(1000)
        ABS(CHECKSUM(NEWID())) % 200,
        DATEADD(day, CHECKSUM(NEWID()) % (3 * 360), GETDATE())
    FROM sys.all_columns A, sys.all_columns B
    go 100

select * from  test_mem where itemid=28 order by date

执行代码后执行计划如图1-1

图1-1

可以看出如此小的数据集排序居然消耗如此恐怖的内存数据量级,这样简单查询如果数据量再大些完全可能严重影响吞吐.

问题分析:通过执行计划我们发现只是一个简单的聚集索引扫描加上一个排序.问题就出现在聚集索引扫描上,通过语义分析我们发现我们的那个Itemid=28也包含在聚集索引扫描中过滤了,但优化器在做内存评估时并未注意到此状况,还是按照全表的相关内存大小评估的.

我们可以根据行大小大概算出优化器”认为”的数据大小.

Select 100000.0*4051.0/1024.0/1024.0 (约等于386MB!)

原来优化器以为他要对386MB的数据排序…

问题总结:优化器在做聚集索引扫描时同时为我们做了Filter过滤,但对接下来的内存评估时确忽略了运算符中的过滤.致使内存评估出现严重问题.

解决:了解了问题点后解决就简单了.在去年6月份的Pass分享中我曾经提过Filter运算符,我们只需让他在我们的执行计划中重现即可.

Trace Flag 9130 可以使得这个运算符可以重现.

Code

select * from  test_mem where itemid=28 order by date
option(querytraceon 9130)

可以通过执行计划看出,内存授予正常,如图1-2所示

图1-2

注:此坑一旦踩上影响着实不小,看到的朋友请扩散.

后记:此问题我已经反应给微软的CSS团队.

时间: 2024-10-09 23:29:32

SQL Server 优化器特性导致的内存授予相关BUG的相关文章

高老大 ‘SQL Server 优化器特性导致的内存授予相关BUG’ 学习笔记

今天高老大出了好文章.在这里 自己本来对这一块比较混乱,正好借这个机会学习一下. 就用高老大的脚本.需要的直接去他那里找吧,这里就省了. 加查询优化标记前后对比 可以看到GrantedMemory是504928KB,大约是213096/1024=208.101562MB(这里的那个值好像每次都有差别,但是差距不太大.不影响效果) 加上跟踪标记后 4560/1024大概只有4MB吧. 差别很大吧~ 其实这里这些值还可能通过查询计划的XML里看,里面有更详细的信息. 如 <QueryPlan Deg

SQL Server优化器特性-隐式谓词

原文:SQL Server优化器特性-隐式谓词 我们都知道,一条SQL语句提交给优化器会产生相应的执行计划然后执行输出结果,但他的执行计划是如何产生的呢?这可能是关系型数据库最复杂的部分了.这里我为大家介绍一个有关SQL Server优化器的特性-隐式谓词,并简单介绍在此特性下如何根据场景控制优化器的行为. 在这里我通过一个简单的实例来给大家说明下. code CREATE TABLE T1 (A INT, B INT) CREATE TABLE T2 (A INT, B INT) set sh

SQL Server优化器特性-动态检索

前段时间我写的文章SQL Server 隐式转换引发的躺枪死锁 中有的朋友评论回复说在SQL2008R2测试时并未出现死锁,自己一测果然如此,因此给大家带来的疑惑表示抱歉,这里我就解释下其原因. 回顾:SQL2012中发生死锁的原因已经向大家解释了,因为隐式转换造成的表扫描扩大了锁规模.但在SQL2008R2中就未有同样的现象出现,很显然锁规模没有扩大,原因在于SQL Server的优化器为我们做了额外的事情-动态检索 动态检索:基于索引查找的优势,SQL Server(部分版本)会尝试将一些情

SQL Server 优化器+SQL 基础

http://www.cnblogs.com/shanksgao/tag/%E4%BC%98%E5%8C%96%E5%99%A8/ http://www.cnblogs.com/double-K/category/759248.html http://www.cnblogs.com/zhijianliutang/category/636063.html http://www.cnblogs.com/lonelyxmas/p/4685085.html       stack生成          

win10 升级导致找不到SQL Server配置管理器

1.背景 SQL Server配置管理器可用来管理与SQL Server相关联的服务.配置SQL Server使用的网络协议以及从SQL Server客户端计算机管理网络连接配置.但是win10从1709升级到1803,升级成功后发现SQL SERVER配置管理器找不到了,以为又是win10给我删除了文件,搜索了下发现有人与我同样的问题,解决方案如下. 2.解决方案 2.1.可以通过:计算机-->右键-->管理-->服务应用程序,但是我不太喜欢点击这么多次鼠标. 2.2.通过[运行]调出

SQL Server优化

虽然查询速度慢的原因很多,但是如果通过一定的优化,也可以使查询问题得到一定程度的解决. 查询速度慢的原因很多,常见如下几种: 没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) I/O吞吐量小,形成了瓶颈效应. 没有创建计算列导致查询不优化. 内存不足 网络速度慢 查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) sp_lock, sp_who, 活动的用户查看,原因是读写竞争资源. 返回了不必要的行和列 查

SQL Server优化50法

查询速度慢的原因很多,常见如下几种:    1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)    2.I/O吞吐量小,形成了瓶颈效应.    3.没有创建计算列导致查询不优化.    4.内存不足    5.网络速度慢    6.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)    7.锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)    8.sp_lock,sp_who,活动的用户查看,原因是读写竞争资源.    9.返回了不必要的行和列   

SQL Server 2014新特性——Buffer Pool扩展

Buffer Pool扩展 Buffer Pool扩展是buffer pool 和非易失的SSD硬盘做连接.以SSD硬盘的特点来提高随机读性能. 缓冲池扩展优点 SQL Server读以随机读为主,SQL Server IO分为2部分:buffer pool管理方式,和buffer pool. SQL Server 从磁盘中读入数据,并且存放在buffer pool中以供读取和修改,修改完之后脏数据还是放在buffer pool中,当内存紧张执行lazy write把脏数据写入磁盘,并且释放内存

谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》

原文:谈谈我的微软特约稿:<SQL Server 2014 新特性:IO资源调控> 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 篡写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源调控器: 第二部分:SQL Server中资源调控器: 第三部分:SQL Server资源调控器运用场景—CPU: 第四部分:SQL Server资源调控器运用场景—IO: 第五部分:总结: 第六部分:作者简介: