T-SQL中的十大注意事项

转载自:http://www.cnblogs.com/CareySon/archive/2012/10/11/2719598.html

1.在生产环境中不要出现Select *

这一点我想大家已经是比较熟知了,这样的错误相信会犯的人不会太多。但我这里还是要说一下。

不使用Select *的原因主要不是坊间所流传的将*解析成具体的列需要产生消耗,这点消耗在我看来完全可以忽略不计。更主要的原因来自以下两点:

  • 扩展方面的问题
  • 造成额外的书签查找或是由查找变为扫描

扩展方面的问题是当表中添加一个列时,Select *会把这一列也囊括进去,从而造成上面的第二种问题。

而额外的IO这点显而易见,当查找不需要的列时自然会产生不必要的IO,下面我们通过一个非常简单的例子来比较这两种差别,如图1所示。

图1.*带来的不必要的IO

2.声明变量时指定长度

这一点有时候会被人疏忽,因为对于T-SQL来说,如果对于变量不指定长度,则默认的长度会是1.考虑下面这个例子,如图2所示。

图2.不指定变量长度有可能导致丢失数据

3.使用合适的数据类型

合适的数据类型首先是从性能角度考虑,关于这一点,我写过一篇文章详细的介绍过,有兴趣可以阅读:对于表列数据类型选择的一点思考,这里我就不再细说了

不要使用字符串类型存储日期数据,这一点也需要强调一些,有时候你可能需要定义自己的日期格式,但这样做非常不好,不仅是性能上不好,并且内置的日期时间函数也不能用了。

4.使用Schema前缀来选择表

解析对象的时候需要更多的步骤,而指定Schema.Table这种方式就避免了这种无谓的解析。

不仅如此,如果不指定Schema容易造成混淆,有时会报错。

还有一点是,Schema使用的混乱有可能导致更多的执行计划缓存,换句话说,就是同样一份执行计划被多次缓存,让我们来看图3的例子。

图3.不同的schema选择不同导致同样的查询被多次缓存

5.命名规范很重要

推荐使用实体对象+操作这种方式,比如Customer_Update这种方式。在一个大型一点的数据库会存在很多存储过程,不同的命名方式使得找到需要的存储过程变得很不方便。因此有可能造成另一种问题,就是重复创建存储过程,比如上面这个例子,有可能命名规范不统一的情况下又创建了一个叫UpdateCustomer的存储过程。

6.插入大量数据时,尽量不要使用循环,可以使用CTE,如果要使用循环,也放到一个事务中

这点其实显而易见。SQL Server是隐式事务提交的,所以对于每一个循环中的INSERT,都会作为一个事务提交。这种效率可想而知,但如果将1000条语句放到一个事务中提交,效率无疑会提升不少。

打个比方,去银行存款,是一次存1000效率高,还是存10次100?下面,根据吉日的要求,补个例子,见代码1.

CREATE TABLE dbo.TestInsert
(
	Number INT PRIMARY KEY
);
--循环插入,不给力,我的笔记本45秒
DECLARE @index INT;
SET @index = 1;

WHILE @index <= 100000
BEGIN
	INSERT dbo.TestInsert(Number) VALUES( @index);
	SET @index = @index + 1;
END

--放到一个事务中循环,略好,但也不是最好,我的笔记本1秒
BEGIN TRAN
DECLARE @index INT;
SET @index = 1;

WHILE @index <= 100000
BEGIN
	INSERT dbo.TestInsert(Number) VALUES( @index);
	SET @index = @index + 1;
END

COMMIT

--批量插入,10W行,显示0秒,有兴趣的同学改成100W行进行测试
INSERT dbo.TestInsert(Number)
	SELECT TOP (100000) rn = ROW_NUMBER() OVER
		(ORDER BY c1.[object_id])
		FROM sys.columns AS c1
		CROSS JOIN sys.columns AS c2
		CROSS JOIN sys.columns AS c3
		ORDER BY c1.[object_id];

--CTE方式,和上面那种方式大同小异,也是批量插入,比如:
WITH cte AS(
	SELECT TOP (100000) rn = ROW_NUMBER() OVER
		(ORDER BY c1.[object_id])
		FROM sys.columns AS c1
		CROSS JOIN sys.columns AS c2
		CROSS JOIN sys.columns AS c3
		ORDER BY c1.[object_id]
)
INSERT dbo.TestInsert(Number) SELECT rn FROM cte

代码1.几种插入方式的比较

7.where条件之后尽量减少使用函数或数据类型转换

换句话说,WHERE条件之后尽量可以使用可以嗅探参数的方式,比如说尽量少用变量,尽量少用函数,下面我们通过一个简单的例子来看这之间的差别。如图4所示。

图4.在Where中使用不可嗅探的参数导致的索引查找

对于另外一些情况来说,尽量不要让参数进行类型转换,再看一个简单的例子,我们可以看出在Where中使用隐式转换代价巨大。如图5所示。

图5.隐式转换带来的性能问题

8.不要使用旧的连接方式,比如(from x,y,z)

可能导致效率低下的笛卡尔积,当你看到下面这个图标时,说明查询分析器无法根据统计信息估计表中的数据结构,所以无法使用Loop join,merge Join和Hash Join中的一种,而是使用效率地下的笛卡尔积。

>   这里我再补充一点,我说得是“可能”导致,因为上面这个查询可能作为中间结果或是子查询,当你忘写了where条件时,会是笛卡尔积。你在最终结果中再用where过滤,可能得到的结果一模一样,但是中间的过程却大不相同

所以,尽量使用Inner join的方式替代from x,y,z这种方式。

9.使用游标时,加上只读只进选项

首先,我的观点是:游标是邪恶的,尽量少用。但是如果一定要用的话,请记住,默认设置游标是可进可退的,如果你仅仅设置了

declare c cursor

    for

这样的形式,那么这种游标要慢于下面这种方式。

 declare c cursor

    local static read_only forward_only

    for…

所以,在游标只读只进的情况下,加上上面代码所示的选项。

10.有关Order一些要注意的事情

首先,要注意,不要使用Order by+数字的形式,比如图6这种。

图6.Order By序号

当表结构或者Select之后的列变化时,这种方式会引起麻烦,所以老老实实写上列名。

还有一种情况是,对于带有子查询和CTE的查询,子查询有序并不代表整个查询有序,除非显式指定了Order By,让我们来看图7。

图7.虽然在CTE中中有序,但显式指定Order By,则不能保证结果的顺序

原文地址:https://www.cnblogs.com/gered/p/8358762.html

时间: 2024-10-11 17:43:51

T-SQL中的十大注意事项的相关文章

SQL Server DBA十大必备工具使生活轻松

[IT168 技术]曾经和一些DBA和数据库开发人员交流时,问他们都用过一些什么样的DB方面的工具,大部分人除了SSMS和Profile之外,基本就没有使用过 其他工具了;诚然,SSMS和Profile足够强大,工作的大部分内容都能通过它们搞定,但是MS.第三方公司甚至是个人开发者为SQLServer提 供了很多其他的工具,如果你能充分的掌握这些工具,无疑会给我们数据库的管理.优化.测试和排错节省大量的时间和精力,下面就来介绍除SSMS和 Profile之外的其他有用的工具. NO1: PD(P

机器学习与数据挖掘中的十大经典算法

背景: top10算法的前期背景是吴教授在香港做了一个关于数据挖掘top10挑战的一个报告,会后有一名内地的教授提出了一个类似的想法.吴教授觉得非常好,开始着手解决这个事情.找了一系列的大牛(都是数据挖掘的大牛),都觉得想法很好,但是都不愿自己干.原因估计有一下几种:1.确实很忙2.得罪人3.一系列工作很繁琐等等.最后和明尼苏达大学的Vipin Kumar教授一起把这件事情承担下来.先是请数据挖掘领域获过kdd和icdm大奖的十四个牛人提名候选,其中一人因为确实很忙,正从ibm转行到微软,吴教授

数学建模学习笔记(建模中的十大常用算法总结)

数学建模中的十大常用算法 1.    蒙特卡洛方法: 又称计算机随机性模拟方法,也称统计实验方法.可以通过模拟来检验自己模型的正确性. 2.    数据拟合.参数估计.插值等数据处理 比赛中常遇到大量的数据需要处理,而处理的数据的关键就在于这些方法,通常使用matlab辅助,与图形结合时还可处理很多有关拟合的问题. 3.    规划类问题算法: 包括线性规划.整数规划.多元规划.二次规划等:竞赛中又很多问题都和规划有关,可以说不少的模型都可以归结为一组不等式作为约束条件,几个函数表达式作为目标函

Go开发中的十大常见陷阱[译]

原文: The Top 10 Most Common Mistakes I've Seen in Go Projects 作者: Teiva Harsanyi 译者: Simon Ma 我在Go开发中遇到的十大常见错误.顺序无关紧要. 未知的枚举值 让我们看一个简单的例子: type Status uint32 const ( StatusOpen Status = iota StatusClosed StatusUnknown ) 在这里,我们使用iota创建了一个枚举,其结果如下: Stat

职场中的十大低级错误

一.诚实 无论任何人和你交流,或者,为了某一目的,你和别人交流,记得说实话,你可以保持不说的权利,一旦开口,一定是以诚待人,实话实说. 尤其是上司向你询问一些事情,知道就是知道,不知道,别信口开河.另外,没有不透风的墙,你说的每一句话,都会被传出去,所以,千万别撒谎. 二.有始有终 职场新人,经常会接受一些任务,有的人不知道如何做,就拖延了,上级有时候会忘记,于是,新人庆幸老板没有继续找他.熟不知,有任务,必然有原因,即便是老板忘记,自己也该及时汇报进展,做得好与不好,姑且不论,但一定要给个交代

DevOps热门发展趋势中的十大误区

如今的IT企业全部是自动化.新一代的代码和应用将我们带进一个融合了基础设施和云计算的时代,企业原有系统正在遭到这些新赶上的庞大的新环境的挑战. 因此,DevOps(Development和Operations的组合)作为一项新的业务脱颖而出,它的出现旨在解决复杂的系统管理员和开发者每天要面对的信息技术问题.尽管有一些组织也在实施DevOps 的方法,但还是有很多人不能完全理解DevOps 具体是什么,他们要么是抗拒,要么是意识不到这种部署的优点. DevOps是一组方法.过程与系统的统称,用于促

1000多个项目中的十大JavaScript错误以及如何避免

通过统计数据库中的1000多个项目,我们发现在 JavaScript 中最常出现的错误有10个.下面会向大家介绍这些错误发生的原因以及如何防止. 对于这些错误发生的次数,我们是通过收集的数据统计得出的.Rollbar 会收集每个项目中的所有错误,并总结每个错误发生的次数,然后通过各个错误的特征进行分组. 下图是发生次数最多的10大 JavaScript 错误: 下面开始深入探讨每个错误发生的情况,以便确定导致错误发生的原因以及如何避免. 1.   Uncaught TypeError: Cann

产品不要被技术绑架的十大注意事项(转)

“不可能的:有难度的:你懂不懂技术的:这个功能要放在二期才能做:要做可以但需要时间:把那个项目停掉我就给你做……”,如果经常听到技术这样说,那你的产品很有可能已经被技术绑架了,接下来你想再多的功能,只要技术说不可以那就没戏. 1.正确选人 ——做网站的技术开发,必须是个技术牛人,要像科学怪人那样的人最好,为实现一个功能可以两天不睡觉的主.千万不要找一个所谓的高级架构师之类的高人,其实这种人连最简单的功能也不会开发了. 2.严禁不可能 ——如果一个程序员说“不可能的”,那他应该去屎.做技术的就是把

Python中的十大图像处理工具

转自:微信博客 机器学习研究会订阅号 微信号 功能介绍机器学习研究会由百度七剑客雷鸣先生创办,旨在推动AI的技术发展和产业落地.参与组织北大.清华”AI前沿与产业趋势“公开课,广泛的和高校.企业.创业.VC开展合作,自身也参与优秀AI项目的投资和孵化. 本文主要介绍了一些简单易懂最常用的Python图像处理库 当今世界充满了各种数据,而图像是其中高的重要组成部分.然而,若想其有所应用,我们需要对这些图像进行处理.图像处理是分析和操纵数字图像的过程,旨在提高其质量或从中提取一些信息,然后将其用于某