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,一经查实,立即删除!

相关文章

React 回忆录(三)使用 React 渲染界面

Hi 各位&#xff0c;欢迎来到 React 回忆录&#xff01;? 在上一章中&#xff0c;我介绍了 React 框架的“五大特点”&#xff1a;虚拟DOM&#xff0c;组件化&#xff0c;声明式代码&#xff0c;单向数据流和纯粹的 JavaScript 语法。在本章中&#xff0c;我们将谈到 React 是…

linux java javac版本_linux下java 和 javac version 不一致问题

centos下我新安装了个jdk1.7的版本 &#xff0c;vi profile 之后 java -version 是新版本&#xff0c;想在看看javac -version 发现还是1.6的之前安装了1.6的 那好咱就卸载他查找Java 版本信息rpm -qa|grep java返回如下信息 xorg-x11-drv-savage-2.1.1-5.fc6avahi-glib-0.6.16…

electron 打包_Vue3+Electron整合方式

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

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

第37套&#xff1a; 给定程序中&#xff0c;函数fun的功能是:在形参ss所指字符串数组中&#xff0c;查找含有形参substr所指子串的所有字符串并输出&#xff0c;若没找到则输出相应信息。ss所指字符串数组中共有N个字符串&#xff0c;且串长小于M。程序中库函数strstr(s1, s2)…

ABAP编程中对内表的定义,后面接一个OCCURS (n)是代表什么意思。

对内表的定义&#xff0c;我只说下有没occurs的区别。**DATA: BEGIN OF itab OCCURS 0,* matnr LIKE mara-matnr,* maktx LIKE makt-maktx,* END OF itab.**SELECT * FROM makt INTO CORRESPONDING FIELDS OF TABLE itab .**LOOP AT itab.* WRITE:/* itab-matnr,* itab-m…

Linux按照时间顺序列出文件

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

java释放list_Java中List集合中subList的坑

参考博主http://blog.csdn.net/xuweilinjijis/article/details/9037635先看List接口subList方法的javadocThe returned list is backed by this list, so non-structural* changes in the returned list are reflected in this list, and vice-versa.* The returned list suppo…

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

第38套&#xff1a; 函数fun的功能是&#xff1a;把形参a所指数组中的奇数按原顺序依次存放到a[0]、 a[1]、a[2]、……中&#xff0c;把偶数从数组中删除&#xff0c;奇数个数通过函数值返回。例如&#xff1a;若a所指数组中的数据最初排列为&#xff1a;9、1、4、2、3、6、5、…

RestKit

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

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

第39套&#xff1a; 给定程序中&#xff0c;函数fun的功能是:在形参ss所指字符串数组中&#xff0c;删除所有串长超过k的字符串&#xff0c;函数返回所剩字符串的个数。ss所指字符串数组中共有N个字符串&#xff0c;且串长小于M。 请在程序的下划线处填入正确的内容并把下划线…

java判断是否包含张三_c# 数组 字符串 C#中判断字符串中包含某个字符

Nodejs windows的安装0.下载地址: http://nodejs-org.qiniudn.com/ https://nodejs.org/download/ https://nodejs.org/en/ 1.基本就是一路N ...跨平台网络抓包工具-Microsoft Message AnalyzerMicrosoft Message Analyzer (MMA 2013)是微软最受欢迎的Netmon的最新版本. 在Netm…

python能开发游戏吗_python可以开发游戏吗,python能开发游戏吗

Q2&#xff1a;用python能制作游戏吗 能&#xff0c;但不适合。 用锤子能造汽车吗&#xff1f; 谁也没法说不能吧&#xff1f;地球上也有很多汽车&#xff0c;是用锤子造出来的。。。。但一般来说&#xff0c;还是用工业机器人更合适对吗&#xff1f; 比较大型的&#xff0c;使…

golang log日志

写入日志文件 func main() {file, err : os.Create("test.log")if err ! nil {log.Fatalln("fail to create test.log file!")}logger : log.New(file, "", log.Llongfile)// 写入文件log格式&#xff1a;/Users/zhou/go/src/zhouTest/test.go:2…

[Andriod官方训练教程]保存数据之保存键-值对的集合

原文地址&#xff1a;https://developer.android.com/training/basics/data-storage/shared-preferences.html ------------------------------------------------------------------------------------------------------------------------------- If you have a relatively …

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

第40套&#xff1a; 给定程序中已建立一个带有头结点的单向链表&#xff0c;链表中的各结点按结点数据域中的数据递增有序链接。函数fun的功能是&#xff1a;把形参x的值放入一个新结点并插入到链表中&#xff0c;插入后各结点数据域的值仍保持递增有序。 请在程序的下划线处填…

java里面有控制器吗_mvc中 控制器部分可以使用Javabean完成吗?为什么?

模型-视图-控制器(MVC)是80年代Smalltalk-80出现的一种软件设计模式&#xff0c;现在已经被广泛的使用。1、模型(Model)模型是应用程序的主体部分。模型表示业务数据&#xff0c;或者业务逻辑.2、视图(View)视图是应用程序中用户界面相关的部分&#xff0c;是用户看到并与之交互…

python时间计算_python计算两日期之间工作日时长

1. 原因&#xff1a;使用dateutil的rrule时&#xff0c;计算速度比较慢 def axx(): from dateutil import rrule received_time datetime.datetime.strptime(2019-04-21 23:00:00, %Y-%m-%d %H:%M:%S) complete_time datetime.datetime.strptime(2019-04-22 01:00:00, %Y-%m-…

QSlider QLCDNumber 最常用的函数和 信号槽 (以后用到在加)

QLCDNumber : 函数: 槽&#xff1a; display(int); QSlider: 函数: setMinimum(int); setMaximum(int); 信号&#xff1a; valueChanged(int); 转载于:https://www.cnblogs.com/lc-cnblong/archive/2013/02/06/2907680.html

【进阶技术】一篇文章搞掂:Spring高级编程

本文篇幅较长&#xff0c;建议合理利用右上角目录进行查看&#xff08;如果没有目录请刷新&#xff09;。 本文基于《Spring5高级编程》一书进行总结和扩展&#xff0c;大家也可以自行研读此书。 十一、任务调度 任务调度主要由三部分组成 &#xff1a; 任务&#xff1a;即需要…