Sql语句编写经验(待完善),请有兴趣的朋友帮忙完善、修改
见笑,收集了一点经验,主要是网上朋友们的作品。请大家帮忙修改完善
主要目的:书写优化sql语句之前可以有一个总体概念。一些具体的语法等等还是察看联机帮助。
Sql语句编写经验和优化措施(不断增加)
一. 书写杂项
1
二. Sql语句杂项
1 尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。
2 注意where子句的写法,必须考虑语句顺序。应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序和索引顺序一致,范围从大到小。
3 不要在where子句中的“=”左边进行函数、算术运算符或者其他表达式计算,否则系统将可能无法正确使用索引。尽量使用>=,不要使用>
4 尽量使用exists代替select count(1)来判断是否存在纪录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。
5 不考虑效率的情况下可以使用or,最好使用union代替。
6 注意表之间连接的数据类型,避免不同类型之间的连接。
7 注意insert .update 操作的数据量,防止与其他应用冲突。如果数据量超过200个数据页面(400K),那么系统将会进行锁升级,页级锁会升级成表级锁。
8尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。
三. 关于表、视图
1 开发人员如果用到其他库的table 或者view,务必在当前库中建立view来实现跨库操作,最好不要直接使用”database.dbo.table”
因为sp_depends不能显示出该sp所使用的跨库table或者view,不方便校验。
2 尽量避免反复访问同一张表或者几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表,然后再做连接。
3 避免频繁的创建、删除临时表。
4 在新建临时表时,如果一次性插入数据量很大,那么使用select into 代替 create table,避免log,提高速度。如果数据量不大,为了缓和系统表资源,建议先create table,然后insert。删除的时候也有truncate和delete的区别。删除的时候要先truncate然后drop,这样可以避免系统表较长的时间锁定。
5 避免用大的临时表与其他大表的连接查询和修改,减低系统表的负担,因为这种操作会在一条语句中多次使用tempdb的系统表。
6 标准化的数据库逻辑设计包括用夺得,有相互关系的窄表来代替很多列的长数据表.
由于表窄,因此可以使排序和建立索引更为迅速,由于多表,所以多簇的索引成为可能,将可以建立更窄更紧凑的索引,没个标中可以由少一些的索引,因此可以提高insert update delete 等的速度,因为这些操作在索引多的情况下会对系统性能产生很大的影响.更少的空值和更少的多余值,增加了数据库的紧凑性.但是由于标准化,所以会增加在获取数据时引用表的数目和其间的连接关系的复杂性.太多的表和复杂的连接关系会降低服务器的性能,因此在这两者之间需要综合考虑.
7 有用的索引同时也可以提高update insert delete的效率.
四. 数据类型,字段
1 identity字段不要作为表的主键与其他表关联,这将会影响到该表的数据迁移.
2 text和image字段属于指针型数据,主要用来存放二进制大型对象(BLOB).这类数据的操作比其他数据类型较慢,因此要避免使用它.
3 日期类型字段的优点是有众多的日期函数支持,因此在日期的大小比较,加减操作上非常简单.但是,在按照日起作为条件的查询操作上也需要使用函数,就慢许多.
4
五. 游标
1 尽量避免使用游标,因为游标的效率较差。如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,那么就要尽量避免在游标循环中再进行表连接的操作。
六. 索引
1 索引的创建要与应用结合考虑,建议大的OLTP表不要超过6个索引。对insert update delete操作较多的表添加索引时候,应该设置较小的填充因子。
2 尽可能使用索引字段作为查询条件,尤其是聚集索引,必要时可以通过index index_name来强制指定索引。对大表查询时候避免使用table scan,必要时候考虑新建索引。
3 在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用该索引中的第一个字段作为条件时才能保证该系统使用该索引,否则该索引将不会被使用。
4. 有大量重复值、且经常有范围查询(between, >,< ,>=,< =)和order by 、group by发生的列,可考虑建立群集索引,对于update,delete等操作较多也考虑建立; select distinct值在50左右数量级别.非群集索引的select distinct 值在400左右,以上数量级别.5个左右不用.
5. 经常同时存取多列,且每列都含有重复值可考虑建立组合索引;
6. 组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列
7. 不要在identity列上建立聚集索引,如果建立那么insert性能就会大大降低.
七. 约束对数据的有效性验证要比规则快.
问题点数:8、回复次数:25Top
1 楼huhanshan013(飞兵团将军)回复于 2004-09-02 15:01:23 得分 1
呵呵,收藏Top
2 楼neverwin(老青蛙)回复于 2004-09-02 15:17:07 得分 0
三. 关于表、视图
1 窄表 尽量没有重复的组(冗余)或者多值的列
2 每个非关键字必须依赖于主关键字,不能依赖于一个组合式主关键字的一个组成部分。
3 一个非关键字段不能依赖于另一个非关键字段。
四. 数据类型,字段
1 列的数据类型要尽量小。char,varchar,binary,varbinary最大长度为8000,nchar,nvarchar最大长度为4000
六. 索引
1 在经常连接(连接表条件,查询where条件中使用),但是没有指定外键(就是有fk指定到该列)的列上指定索引。
二. Sql语句杂项
1 避免相关子查询,也就是说,主查询和自查询的where子句中,不要出现同一个列值的判断。尽量集中到子查询中过滤尽可能多的行。
2 避免使用mathes,like这些困难的正则表达式,他们可能导致无法使用索引。(like 好像很多时候一样使用索引。。。。。。)
一. 书写杂项
1 cup使用率应<75%,内存命中率应该>90%
Top
3 楼lyzzbbgo(需要睡个好觉)回复于 2004-09-02 15:37:33 得分 1
markTop
4 楼neverwin(老青蛙)回复于 2004-09-02 19:07:41 得分 0
upTop
5 楼neverwin(老青蛙)回复于 2004-09-03 08:44:57 得分 0
up agTop
6 楼leo2003(【健者天行】谁伴我闯荡)回复于 2004-09-03 10:02:58 得分 1
收藏,
有不少的错别字Top
7 楼xuelanghun(雪狼魂)回复于 2004-09-03 10:10:59 得分 1
收藏Top
8 楼superxiumu(好好学习,天天向上!)回复于 2004-09-03 10:21:49 得分 1
markTop
9 楼haoK(haoK.Y)回复于 2004-09-03 10:52:12 得分 1
不错!!
有点疑问:
"count(1)比count(*)更有效率"
看《联机丛书》..
COUNT(*)
指定应该计算所有行以返回表中行的总数。COUNT(*) 不需要任何参数,而且不能与 DISTINCT 一起使用。COUNT(*) 不需要 expression 参数,因为根据定义,该函数不使用有关任何特定列的信息。COUNT(*) 返回指定表中行的数量而不消除副本。它对每行分别进行计数,包括含有空值的行。
注意:“该函数不使用有关任何特定列的信息”
感觉SQL SERVER 应该对count(*)作了优化!!
Top
10 楼neverwin(老青蛙)回复于 2004-09-03 11:53:13 得分 0
错别字没来得及改。。。。
count(1)是不是比count(*)有效率这个不知道,如果是,为什么,请教高手ing
请大家加入自己的经验。。。Top
11 楼haoK(haoK.Y)回复于 2004-09-03 12:32:20 得分 1
尽量使用表变量代替临时表,减少i/o次数
发掘自定义函数的威力,尤其是返回表的函数,可以极大扩展开发的手段
Top
12 楼laker_tmj(laker)回复于 2004-09-03 16:41:33 得分 1
五. 游标
1 尽量避免使用游标,因为游标的效率较差。如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,那么就要尽量避免在游标循环中再进行表连接的操作。
???
超过1万行,
避免在游标循环中再进行表连接的操作
以上兩點不確認!Top
13 楼hanbinghai(海宁)回复于 2004-09-03 16:47:18 得分 0
upTop
14 楼The_Gathering(蒜茸粉丝蒸蚬贝)回复于 2004-09-03 16:55:10 得分 0
好东西啊,收藏先。
不过,对于这些经验,有为什么要这么做的理由就好了
例如:
尽量使用>=,不要使用>
为什么呢?Top
15 楼cheny1234(咩)回复于 2004-09-03 17:10:17 得分 0
学习Top
16 楼neverwin(老青蛙)回复于 2004-09-03 17:11:54 得分 0
一. 书写杂项
如果需要在数据库中区分全角/半角字符
选择使用Chinese_PRC_CI_AS_WS排序规则Top
17 楼neverwin(老青蛙)回复于 2004-09-03 17:15:22 得分 0
很多地方要说为什么,不知道。。。。。-_-!!
可以带着这些问题学习。总比不知道的好。
大家补充阿。。。。Top
18 楼neverwin(老青蛙)回复于 2004-09-04 16:29:20 得分 0
upTop
19 楼pengda1i(冒牌大力 V0.4)回复于 2004-09-04 16:37:52 得分 0
8错
Top
20 楼XiaoZhengGe(建议集体去日本强奸·让他们的子孙变成华裔)回复于 2004-09-04 20:08:37 得分 0
没有试过,楼主写的有待我去实验!Top
21 楼cgsun(colin)回复于 2004-09-05 16:28:48 得分 0
haoTop
22 楼zlp321002(Life Is Good,Let's Shine)回复于 2004-09-05 16:35:47 得分 0
收!Top
23 楼asuntea(.net)回复于 2004-10-15 17:18:03 得分 0
gffTop
24 楼xjp6688(大平/要做必须最好)回复于 2004-10-15 17:41:22 得分 0
好!Top
25 楼icedut(冰-装修进行中)回复于 2004-10-15 17:42:37 得分 0
收藏Top




