在内存中创建临时表和表变量
在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈。在SQL Server 2016的内存(Memory-Optimized)数据库中,如果考虑使用内存优化结构来存储临时表,表变量,表值参数的数据,那么将完全消除IO操作的负载消耗,发挥大内存的优势,大幅提高数据库的性能。
在SQL Server 2016中,能够直接创建内存优化的表类型,表变量和表值参数的数据只存储在内存中;不能直接在内存中创建临时表,但是,SQL Server提供一个变通方法(Workaround),通过行级安全RLS(Row-Level-Security)控制,指定只有当前Session才能访问特定的数据,将内存优化表转换为Session级别的临时表,间接实现临时表的局部性和自动清空特性。
一,内存优化表类型(Memory-Optimized Table Type)
内存优化表类型定义的表变量,表值参数能够大幅提高效率(efficiency),有4个显著的特点:
- 数据仅存储在内存中,在读写数据时,不会产生任何的IO消耗,消除了tempdb的竞争和利用率;
- 必须有一个索引,Hash 或 Nonclustered 都行;每一个内存优化表必须创建一个索引;
- 只需要指定启用内存优化:MEMORY_OPTIMIZED = ON,只持久化Schema;
- 必须先创建表类型,后创建表值变量;
1,创建内存优化表类型
![](/assets/blank.gif)
CREATE TYPE dbo.TypeTable AS TABLE ( Column1 INT NOT NULL, Column2 VARCHAR(10) NOT NULL, INDEX idxName NONCLUSTERED(Column1) ) WITH(MEMORY_OPTIMIZED = ON);
![](/assets/blank.gif)
2,创建内存优化表变量
declare @Table dbo.TypeTable
二,创建“临时内存优化表”
在Disk-Base数据库中,局部临时表#temp的作用域是session,创建在tempdb中,一旦session生命周期结束,系统自动回收其存储空间。在SQL Server 2016中,不能直接在tempdb中创建内存优化表。要使用临时内存优化表,有一个变通的方法,在DB中创建内存优化表,通过Row-Level-Security控制Session能够访问的数据行,间接实现Session级别的临时表。
Step1,创建内存优化表,只持久化Table Schema
![](/assets/blank.gif)
CREATE TABLE dbo.SessionTempTable ( Column1 INT NOT NULL, Column2 NVARCHAR(4000) NULL, SpidFilter SMALLINT NOT NULL DEFAULT (@@spid), INDEX ix_SpidFiler NONCLUSTERED (SpidFilter), --INDEX ix_SpidFilter HASH (SpidFilter) WITH (BUCKET_COUNT = 64), CONSTRAINT CHK_soSessionC_SpidFilter CHECK ( SpidFilter = @@spid ), ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY); go
![](/assets/blank.gif)
Step2,创建RLS,控制用户只能访问当前Session的数据
推荐为Predicate function 和 Security Policy创建单独的Schema,然后在该Schema下创建Predicate function 和 Security Policy,对于Predicate function必须使用 NATIVE_COMPLIATION选项创建。
![](/assets/blank.gif)
create schema rls authorization dbo;CREATE FUNCTION rls.fn_SpidFilter (@SpidFilter smallint) RETURNS TABLE WITH SCHEMABINDING , NATIVE_COMPILATION AS RETURN SELECT 1 AS fn_SpidFilter WHERE @SpidFilter = @@spid; goCREATE SECURITY POLICY rls.soSessionC_SpidFilter_Policy ADD FILTER PREDICATE rls.fn_SpidFilter(SpidFilter) ON dbo.SessionTempTable WITH (STATE = ON); go
![](/assets/blank.gif)
Step3,使用内存优化临时表
- 表名替换:使用 dbo.Temp 代替 #Temp;
- 不能创建和删除临时表:
- 移除代码“create table #temp”,使用“delete from dbo.Temp”子句取代,将旧数据清空;
- 移除代码“drop table #temp”,建议使用 “delete from dbo.Temp” 子句,在当前Session结束前将当前Session产生的数据清空,节省内存空间;
虽然临时表的使用和管理有点麻烦,但是,这点麻烦和大幅的性能提升来比,微不足道,建议使用内存优化表来代替临时表,体验飞一般的速度。
三,维护
1,通过RLS来创建内存临时表,如何清理临时表占用的内存空间?
试想出现异常,在当前Session将海量数据插入到临时表之后,Session异常终止,此时,Session没有来得及清空(Purge)临时表中的数据,这些数据仍然驻留在内存中。如果这种异常出现的频率很高,那么会导致内存优化表消耗大量的系统内存,必须有机制来定期清理临时表占用的内存空间。
step1,创建一个用户,RLSAdmin,授予db_owner的权限
--create User create user RLSAdmin without login; alter role db_owner add member RLSAdmin; go
step2,修改Predicate Function,如果用户是RLSAdmin,允许访问Base Table的所有数据行;
![](/assets/blank.gif)
--create predicate function CREATE FUNCTION rls.fn_SpidFilter (@SpidFilter smallint) RETURNS TABLE WITH SCHEMABINDING , NATIVE_COMPILATION AS RETURN SELECT 1 AS fn_SpidFilter WHERE @SpidFilter = @@spid or User_Name()='RLSAdmin'; go
![](/assets/blank.gif)
step3,创建Schedule,定期检查数据库中的临时表,如果发现临时表中的存在未被清理的无效数据,那么删除该部分数据,释放内存。
![](/assets/blank.gif)
execute as RLSAdmin;delete temp from dbo.SessionTempTable temp left join sys.dm_exec_sessions son temp.SpidFilter=s.session_id and s<>@@spid and s.session_id>50 where s.session_id is null; revert;
![](/assets/blank.gif)
该脚本仅仅提供一种思路,在产品环境中,需要多测试,以防错误删除数据。
转载于:https://www.cnblogs.com/chenliyang/p/6548231.html
在内存中创建临时表和表变量相关推荐
- SqlServer 中的临时表与表变量
我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候 ...
- [导入]SQL中的临时表和表变量
我们经常使用临时表和表变量,那现在我们就对临时表和表变量进行一下讨论. 临时表 局部临时表 全局临时表 表变量 临时表 临 时表存储在TempDB数据库中,所有的使用此SQL Server 实例的用户 ...
- sql 表变量 临时表_SQL表变量概述
sql 表变量 临时表 This article explores the SQL Table variables and their usage using different examples. ...
- 关于临时表和表变量的差别1
临时表,表变量,这2个兄弟在平时使用的时候并不会陌生.很多时候我们都借用这2兄弟来进行一下中间结果集的缓存之类的功能.那我就简单说下这2兄弟在查询时候的一些小区别 1.首先我建立了一个表,存放100W ...
- SQL Server中临时表与表变量的区别
我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候 ...
- SQL Server--[转]SQL Server中临时表与表变量的区别
http://blog.csdn.net/skyremember/archive/2009/03/05/3960687.aspx 我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临 ...
- php sql server临时表,SQLServer中临时表与表变量的区别分析
在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候去使用临时表而不使用表变量,有时候去使用表变量而不使用临时表呢? 临时表 临时表与永 ...
- sql语句用变量替换表名_使用内存优化表替换SQL临时表和表变量
sql语句用变量替换表名 TempDB usage can be considered as a performance bottleneck for workloads that use SQL t ...
- 存储过程中引用的常规表,临时表以及表变量是否会导致存储过程的重编译
在存储过程中,经常要引用一些表来存储一些中间数据,用完即删.对于这个中间表,用常规表,临时表或者表变量有什么区别呢? 下面我们看一下这三种中间表是否会造成执行计划的重编译. 首先打开sql serve ...
最新文章
- nginx--之静态服务器
- 【Tools】git提示“warning: LF will be replaced by CRLF”的解决办法
- 2019 ACM-icpc西安邀请赛总结(无题解)
- 大数据开发实战:数据仓库技术
- Excel,Python,SQL?数据分析师的技能树要怎么点?
- 互联网晚报 | 2月21日 星期一 | 北京冬奥会闭幕;天猫将新增菜鸟驿站送货上门服务;上汽奥迪首款电动车型开启预售...
- Java笔记-对称加密AES的使用
- 对当今社会的某些现象的感想
- JavaScript读写.txt文档 - 方法篇
- 深度学习(三十三)CRF as RNN语义分割-未完待续
- python爬取b站评论_学习笔记(1):写了个python爬取B站视频评论的程序
- 12. No More MVC
- html微信窗口阻止滚动条,微信浏览器禁止页面下拉查看网址(不影响页面内部scroll)...
- Todesk一直显示正在连接本地连接
- JavaScript 数据结构与算法(队列)
- SVC(可分层视频编解码)
- 长安链源码学习--提案(Proposer)(五)
- MATLAB画图并将两个图排列在一起
- Radius/Free Radius/Diameter协议
- 基于多特征的技术融合关系预测及其价值评估