SQL Server Insert 操作效率(堆表 VS 聚集索引表)

  “SQL Server的Insert操作在堆表或者聚集索引表的时候,哪个效率更高?为什么高?”

  之前有同事问过我这个问题,为了确保日志库的记录效率,于是我做了简单测试了,首先要先强调几点概念:

 

  堆表:没有聚集索引的表,记录通过IAM页以及PFS页来确定哪页有空闲空间。

  聚集索引表:有聚集索引的表,记录是根据聚集键值所在页的键值逻辑顺序维护的

 

Demo:如下

  分别对堆表和聚集表进行5个并发线程,每个线程各10000次循环插入

 1.  堆表测试

--1.    创建一张堆表
create table Insert_Test (id int identity, name char(200))
go

堆表Insert用时:34.127秒

2.  聚集索引表测试

create table Insert_Test2 (id int identity primary key clustered, name char(200))
go

聚集索引表Insert用时:22.885秒

结果:聚集索引的插入速度比堆表要快10秒以上(个人机器配置不同,时间差异也会高或低,我的本子性能较低)

 

分析

 

  堆表插入:

  每一次insert,总是被插入到表的任意可用空间上,通过IAM找到文件中的哪段区间属于目标表,通过PFS页找出这些区间内的哪些页面有可用空间,如果页面没有可用空间,需要通过GAM页和SGAM页查找将分配的某个表的可用区间。

  聚集索引:

  由于我的聚集键为自增id列,所以每次插入都将集中在最后一个数据页上。

  总体来说:由于堆表插入的行的目标位置没有定义,因此确定在堆表中哪里放置行通常比在有聚集索引的表中放置行的效率低。

 

聚集索引表Insert的弊端

  根据上面分析,聚集索引为自增列时,最后的数据页会成为集中insert的目标页,因此会成为热点,通时,SQL Server 使用闩锁,所以预测大并发insert操作会在最终页产生资源阻塞,实测确实如此:

  (200个并发线程,每个线程执行100次insert操作)

执行过程中,查看等待资源情况

 

select
wait_type,
count(*) as num_waiting_tasks,
sum(wait_duration_ms) as total_wait_time_ms
from sys.dm_os_waiting_tasks
where session_id>50
group by wait_type
order by wait_type

 

  和预测情况一样,98个请求在等待闩锁资源。

  那么,推断如果使用guid作为主键,插入时会分散各个数据页面,进而将热点页平铺开,这点确实有效果,但是拆分页的成本会相当的高,拆分页也是非常损伤性能的。

 

  继续补充个情况,假如你需要长期大量insert操作,不如采用batch,效果会更快,将上面的脚本改为如下:

  

declare @i int 
set @i = 1
while  @i <=10000
beginif @i %5000 = 0beginif (@@TRANCOUNT>0)beginCOMMIT TRANBEGIN TRANendend insert into Insert_Test2 select 'aaa'set @i  =@i + 1
end
if (@@TRANCOUNT>0)
commit tran

单次执行从原先的8秒降为3秒,有兴趣的朋友可以自己测试

  原因简单说下,Insert操作时需要进行预写日志的步骤,每个单独的insert操作都要写一遍ldf文件,这样的性能很低,如果每5000条insert包含在一个事务中后提交,它把很多小的transaction合并成一个大的合适的 transaction来减少磁盘写操作,从而获得极大性能提升。Batch size究竟多大才是最佳的呢?这个取决您的机器,需要你自己测试。

转载于:https://www.cnblogs.com/SQLServer2012/archive/2013/01/30/2882815.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

electron 打包_Vue3+Electron整合方式

教程源码&#xff1a;nofacer/vue3-electron​github.com之前写过一篇文章Vue结合Electron构建跨平台应用&#xff08;TDD&#xff09;。当时的方法后来发现了一个问题&#xff0c;就是打包后的应用拿到其他机子上没法用&#xff0c;原因在于index.html的地址是个绝对路径&…

Linux按照时间顺序列出文件

按照递增时间顺序列出所有文件 ls -ltr -l表示列出长串数据&#xff0c;-t表示按照时间顺序&#xff0c;-r表示将排序的结果反向输出 按照时间递减的顺序列出所有文件 ls -lt 转载于:https://www.cnblogs.com/yongjieShi/p/9395932.html

RestKit

2019独角兽企业重金招聘Python工程师标准>>> Restkit 是一个开源的 objective-c 框架&#xff0c;允许在 iOS 和 Mac OS X 的 Objective-C 中与 RESTful Web 服务进行交互&#xff0c;包含简单的 HTTP request/response API &#xff0c;带有强大的对象映射系统用于…

全国计算机等级考试题库二级C操作题100套(第41套)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

2012年终总结 二

2019独角兽企业重金招聘Python工程师标准>>> 接上文。。。 经过一些搜索和了解之后&#xff0c;最后选定了我现在这个公司。现在&#xff0c;至少我没有感觉到我选错。 刚近公司&#xff0c;进行了新人的入职培训1天&#xff0c;这个主要是了解公司状况。而后&…

python语言包括哪些实现_Python语言基础考察点:python语言基础常见考题(一)

一、python是静态还是动态类型&#xff1f;是强类型还是弱类型&#xff1f; 1、动态强类型语言(不少人误以为是弱类型) 不要傻傻分不清 2、动态还是静态指的是编译期还是运行期确定类型 3、强类型指的是不会发生隐式类型转换 若类型语言强类型语言4、python作为后端语言优缺点 …

由于开发者通过接口修改了菜单配置_开发者说:Seata 0.7.0 版本,你 get 'Metrics' 技能了吗?...

从用户的视角来感受一个开源项目的成长&#xff0c;是我们推出「开发者说」专栏的初衷&#xff0c;即在开发者进行开源项目选型时&#xff0c;提供更为立体的项目信息。专栏所有内容均来自作者原创/投稿&#xff0c;本文是「开发者说」的第9篇&#xff0c;作者郑扬勇&#xff0…

Java 多线程(三) 线程的生命周期及优先级

Java 多线程&#xff08;三&#xff09; 线程的生命周期及优先级 线程的生命周期 线程的生命周期&#xff1a;一个线程从创建到消亡的过程。 如下图&#xff0c;表示线程生命周期中的各个状态&#xff1a; 线程的生命周期可以分为四个状态&#xff1a; 1.创建状态&#xff1a; …

eclipse 导入maven项目_手把手的Spring Boot Web 项目教程,Hello Spring Boot

在开始之前&#xff0c;我们需要去创建一个SpringBoot项目&#xff0c;大家可以去 http://start.spring.io/ 这个网站生成一个项目。如图&#xff0c;这边可以对SpringBoot项目进行详细设置&#xff1a;下面这个web一定要勾选&#xff1a;SpringBoot版本号选择1.5.10全部设置好…

ASP.Net中实现中英文复合检索文本框

前段时间&#xff0c;写一个用户部门的管理页面&#xff0c;需要对后台获取的用户数据实现英汉检索功能。  同时&#xff0c;选定一个选项之后&#xff0c;需要触发事件与后台交互&#xff0c;将该用户所在的部门显示到页面右边的ListBox控件中。 一、Dojo的FilteringSelect组…

sklearn 安装_初识sklearn

我的主业是互联网运营&#xff0c;业余的python爱好者&#xff0c;学习python已经快两年&#xff0c;主攻网络爬虫与数据分析&#xff0c;爬虫能使用代理ip、打码平台、OCR识别、基本的js逆向处理反爬&#xff1b;数据分析主要使用pandas与pyecharts进行可视化&#xff0c;我的…

[工具库]JOJSONBuilder工具类——一键把多个bean对象数据转换为JSON格式数据

本人大四即将毕业的准程序员&#xff08;JavaSE、JavaEE、android等&#xff09;一枚&#xff0c;小项目也做过一点&#xff0c;于是乎一时兴起就写了一些工具。 我会在本博客中陆续发布一些平时可能会用到的工具。 代码质量可能不是很好&#xff0c;大家多担待&#xff01; 代…

mysql long类型_怒肝两个月MySQL源码,我总结出这篇2W字的MySQL协议详解(超硬核干货)!!...

点击上方蓝色“冰河技术”&#xff0c;关注并选择“设为星标”持之以恒&#xff0c;贵在坚持&#xff0c;每天进步一点点&#xff01;作者个人研发的在高并发场景下&#xff0c;提供的简单、稳定、可扩展的延迟消息队列框架&#xff0c;具有精准的定时任务和延迟队列处理功能。…

状压dp之二之三 炮兵阵地/玉米田 By cellur925

一、简单的状压dp 玉米田 题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares…

LockSupport的源码实现原理以及应用

一、为什么使用LockSupport类 如果只是LockSupport在使用起来比Object的wait/notify简单&#xff0c; 那还真没必要专门讲解下LockSupport。最主要的是灵活性。 上边的例子代码中&#xff0c;主线程调用了Thread.sleep(1000)方法来等待线程A计算完成进入wait状态。如果去掉Thr…

python3 爬虫 requests安装_BOSS直聘招聘信息获取之爬虫工具分析

点击蓝色“不太灵光的程序员”关注我哟加个“星标”&#xff0c;每天上午 09:30&#xff0c;干货推送&#xff01;文中使用的组件库仅限于Python语言&#xff0c;由于最近收到一些同学的留言说&#xff0c;按照网上的教程一步一步的学习&#xff0c;却频繁的出现报错&#xff0…

假期周进度总计(四)

本周学习利用OEM工具创建删除表以及对表内数据进行增删改查的操作 一切均通过此工具进行&#xff0c;然后还学到了用SQL *Plus进行相应操作 本周每天4.5个小时&#xff0c;出现的错误就是点击的误操作&#xff0c;可以改正&#xff0c;下周进一步学习Oracle基本操作转载于:http…

Java集合框架(3)

Map(和Collection<E>一样都是集合框架的顶层接口) |--Hashtable:底层是哈希表数据结构&#xff0c;不可以用null对象作为键或值。它是线程同步的。 |--HashMap&#xff1a;底层是哈希表。允许使用null键null值&#xff0c;该集合是不同步的&#xff0c;效率高&#xff0c…

php函数从数组中取出指定的数目,PHP数组函数

1.array_rand()从数组中随机取出一个或多个元素(返回值是&#xff1a;随机元素的键)$arr[js,css,25,php,30];printf(%s,print_r($arr,true));//随机去2个元素$resarray_rand($arr,2);printf(%s,print_r($res,true));2.array_replace()使用后面数组元素相同 key 的值替换 array1…

存储过程 not supported yet_让我们来看看+Redis如何存储和计算一亿用户的活跃度

1前段时间&#xff0c;在网上看到一道面试题&#xff1a;如何用redis存储统计1亿用户一年的登陆情况&#xff0c;并快速检索任意时间窗口内的活跃用户数量。觉得很有意思&#xff0c;就仔细想了下 。并做了一系列实验&#xff0c;自己模拟了下 。还是有点收获的&#xff0c;现整…