临时表

本地临时表

  适合开销昂贵   结果集是个非常小的集合

-- Local Temporary Tables

IF OBJECT_ID('tempdb.dbo.#MyOrderTotalsByYear') IS NOT NULL
DROP TABLE dbo.#MyOrderTotalsByYear;
GO CREATE TABLE #MyOrderTotalsByYear
(
orderyear INT NOT NULL PRIMARY KEY,
qty INT NOT NULL
); INSERT INTO #MyOrderTotalsByYear(orderyear, qty)
SELECT
YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS qty
FROM Sales.Orders AS O
JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate); SELECT Cur.orderyear, Cur.qty AS curyearqty, Prv.qty AS prvyearqty
FROM dbo.#MyOrderTotalsByYear AS Cur
LEFT OUTER JOIN dbo.#MyOrderTotalsByYear AS Prv
ON Cur.orderyear = Prv.orderyear + 1;
GO

全局临时表

CREATE TABLE ##Temp
(
id int,
customer_name nvarchar(50),
age int
) INSERT INTO ##Temp VALUES(1,'老王',20),(2,'老张',30),(3,'老李',25)
-- Global Temporary Tables
CREATE TABLE dbo.##Globals
(
id sysname NOT NULL PRIMARY KEY,
val SQL_VARIANT NOT NULL
); -- Run from any session
INSERT INTO dbo.##Globals(id, val) VALUES(N'i', CAST(10 AS INT)); -- Run from any session
SELECT val FROM dbo.##Globals WHERE id = N'i'; -- Run from any session
DROP TABLE dbo.##Globals;
GO

变量

  

-- Table Variables
DECLARE @MyOrderTotalsByYear TABLE
(
orderyear INT NOT NULL PRIMARY KEY,
qty INT NOT NULL
); INSERT INTO @MyOrderTotalsByYear(orderyear, qty)
SELECT
YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS qty
FROM Sales.Orders AS O
JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate); SELECT Cur.orderyear, Cur.qty AS curyearqty, Prv.qty AS prvyearqty
FROM @MyOrderTotalsByYear AS Cur
LEFT OUTER JOIN @MyOrderTotalsByYear AS Prv
ON Cur.orderyear = Prv.orderyear + 1;
GO

LAG函数

-- with the LAG function
DECLARE @MyOrderTotalsByYear TABLE
(
orderyear INT NOT NULL PRIMARY KEY,
qty INT NOT NULL
); INSERT INTO @MyOrderTotalsByYear(orderyear, qty)
SELECT
YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS qty
FROM Sales.Orders AS O
JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate); SELECT orderyear, qty AS curyearqty,
LAG(qty) OVER(ORDER BY orderyear) AS prvyearqty
FROM @MyOrderTotalsByYear;
GO

表类型

-- Table Types
IF TYPE_ID('dbo.OrderTotalsByYear') IS NOT NULL
DROP TYPE dbo.OrderTotalsByYear; CREATE TYPE dbo.OrderTotalsByYear AS TABLE
(
orderyear INT NOT NULL PRIMARY KEY,
qty INT NOT NULL
);
GO -- Use table type
DECLARE @MyOrderTotalsByYear AS dbo.OrderTotalsByYear; INSERT INTO @MyOrderTotalsByYear(orderyear, qty)
SELECT
YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS qty
FROM Sales.Orders AS O
JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate); SELECT orderyear, qty FROM @MyOrderTotalsByYear;
GO

动态SQL

-- Simple example of EXEC
DECLARE @sql AS VARCHAR(100);
SET @sql = 'PRINT ''This message was printed by a dynamic SQL batch.'';';
EXEC(@sql);
GO

EXEC命令

-- Simple example using sp_executesql
DECLARE @sql AS NVARCHAR(100); SET @sql = N'SELECT orderid, custid, empid, orderdate
FROM Sales.Orders
WHERE orderid = @orderid;'; EXEC sys.sp_executesql
@stmt = @sql,
@params = N'@orderid AS INT',
@orderid = 10248;
GO

使用动态SQL的PIVOT

-- Static PIVOT
SELECT *
FROM (SELECT shipperid, YEAR(orderdate) AS orderyear, freight
FROM Sales.Orders) AS D
PIVOT(SUM(freight) FOR orderyear IN([2006],[2007],[2008])) AS P;

例程

用户自定义函数

存储过程

触发器

错误处理

  表变量创建的语法类似于临时表,区别就在于创建的时候,必须要为之命名。表变量是变量的一种,表变量也分为本地及全局的两种,本地表变量的名称都是以“@”为前缀,只有在本地当前的用户连接中才可以访问。全局的表变量的名称都是以“@@”为前缀,一般都是系统的全局变量,像我们常用到的,如@@Error代表错误的号,@@RowCount代表影响的行数。

DECLARE @News Table
  (
  News_id int NOT NULL,
  NewsTitle varchar(100),
  NewsContent varchar(2),
  NewsDateTime datetime
  )

临时表和表变量的选择

--表变量:
DECLARE @tb table(id int identity(1,1), name varchar(100))
INSERT @tb SELECT id, name
FROM mytable WHERE name like ‘zhang%’ --临时表:
SELECT name, address
INTO #ta FROM mytable
WHERE name like ‘zhang%’

  临时表是利用了硬盘(tempdb数据库) ,表名变量是占用内存,因此小数据量当然是内存中的表变量更快。当大数据量时,就不能用表变量了,太耗内存了。大数据量时适合用临时表。

  表变量缺省放在内存,速度快,所以在触发器,存储过程里如果数据量不大,应该用表变量。

  临时表缺省使用硬盘,一般来说速度比较慢,那是不是就不用临时表呢?也不是,在数据量比较大的时候,如果使用表变量,会把内存耗尽,然后使用 TEMPDB的空间,这样主要还是使用硬盘空间,但同时把内存基本耗尽,增加了内存调入调出的机会,反而降低速度。这种情况建议先给TEMPDB一次分配合适的空间,然后使用临时表。

  临时表相对而言表变量主要是多了I/O时间,但少了对内存资源的占用。数据量较大的时候,由于对内存资源的消耗较少,使用临时表比表变量有更好的性能。

  建议:触发器、自定义函数用表变量;存储过程看情况,大部分用表变量;特殊的应用,大数据量的场合用临时表。

  表变量有明确的作用域,在定义表变量的函数、存储过程或批处理结束时,会自动清除表变量。

  在存储过程中使用表变量与使用临时表相比,减少了存储过程的重新编译量。

  涉及表变量的事务只在表变量更新期间存在。这样就减少了表变量对锁定和记录资源的需求。

  表变量需要事先知道表结构,普通临时表,只在当前会话中可用与表变量相同into一下就可以了,方便;全局临时表:可在多个会话中使用存在于temp中需显示的drop。(不知道表结构情况下临时表方便一些)

  全局临时表的功能是表变量没法达到的。

  表变量不必删除,也就不会有命名冲突,临时表特别是全局临时表用的时候必须解决命名冲突。

  应避免频繁创建和删除临时表,减少系统表资源的消耗。

  在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。

  如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。

  如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。

  慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

  使用表变量主要需要考虑的就是应用程序对内存的压力,如果代码的运行实例很多,就要特别注意内存变量对内存的消耗。

  我们对于较小的数据或者是通过计算出来的推荐使用表变量。

  如果数据的结果比较大,在代码中用于临时计算,在选取的时候没有什么分组的聚合,就可以考虑使用表变量。

  一般对于大的数据结果,或者因为统计出来的数据为了便于更好的优化,我们就推荐使用临时表,同时还可以创建索引,由于临时表是存放在Tempdb中,一般默认分配的空间很少,需要对tempdb进行调优,增大其存储的空间。

  CTE和WITH AS短语结合使用提高SQL查询性能:

  CET要比表变量效率高得多!

  表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。

资料

https://blog.csdn.net/lishimin1012/article/details/54137787

https://www.cnblogs.com/Jessy/archive/2013/06/13/3133958.html

最新文章

  1. Django项目流程(摘抄整理)
  2. QMessageBox 使用方法
  3. BZOJ 1013 球形空间产生器
  4. 最简单的内核模块hello world
  5. eclipse:Tomcat设置jvm,解决java.lang.OutOfMemoryError: Java heap space 堆内存溢出
  6. encode_utf8 把字符编码成字节 微信例子
  7. 交叉编译和使用HTOP
  8. 解析好的静态页面.shtml浏览器无法解析.需要apache解析后再返回给浏览器
  9. JavaScript(第四天)【运算符】
  10. computed计算属性
  11. IPv6绝不仅仅是对IPv4地址长度的增加
  12. vector内存回收
  13. C++ Primer 笔记——重载运算
  14. jsp 进度条
  15. Js/Jquery 关闭 离开或刷新当前页面时提醒,和执行解绑取消提醒
  16. python 如何在一个.py文件中调用另一个.py文件的类
  17. 13 jmeter性能测试实战--FTP程序
  18. Python min() 方法
  19. otunnel : 一个和lcx差不多的端口转发的工具
  20. html开发基础

热门文章

  1. Python-03-流程控制
  2. CSS样式三种形式222
  3. git出现Invalid path
  4. Qt4 和 Qt5 模块的分类
  5. Vue $emit $event 传值(子to父)
  6. javascript Ajax 学习
  7. IIS发布问题解决
  8. 【转载】Sqlserver根据生日计算年龄
  9. TypeScript算法与数据结构-栈篇
  10. Mac下多版本JDK安装及管理