首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

软件工程师老鸟写sql语句的经验之谈

2012-10-23 
程序员老鸟写sql语句的经验之谈做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构

程序员老鸟写sql语句的经验之谈

做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构的设计,sql语句的编写等。因此在开发系统的时候,表结构设计是否合理,sql语句是否标准,写出的sql性能是否优化往往会成为公司衡量程序员技术水平的标准。

?

我们程序员不是dba,不需要时刻关注sql运行时间,想方设法优化表结构,存储空间,优化表读取速度等等,但是在开发系统时,时刻保持优良的写sql语句的作风是很有必要的,这关乎到个人在公司的声誉,嘿嘿,你懂的。。。

?

新来的程序员老鸟,在一个开发团队中,需要表现一下自己的水平,奠定在公司的地位,需要努力表现一把,最简单的从写的sql语句就很容易表现出来,曾经就有一次,一个老程序员,上面定位是要做团队领导的,先历练一下做个制单的模块,列表sql中有一列这位老鸟直接写了个select语句从别的表中取之,而不是用表之间关联得到,一下破坏自己程序员老鸟光辉形象。

?

做技术的还是要注重自己的内涵,提升内功,哈哈。

?

闲话少说,总结一点程序员老鸟写sql顺手拈来的功夫吧:

?

1. 不论一个sql中涉及到多个表,每次都用两个表(结果集)操作,得到新的结果后,再和下一个表(结果集)操作。

?

2. 避免在select f1,(select f2 from tableB ).... from tableA 这样得到字段列。直接用tableA和tableB关联得到A.f1,B.f2就可以了。

?

3.避免隐含的类型转换
?如
?select id from employee where emp_id='8'? (错)
?select id from employee where emp_id=8??? (对)
?emp_id是整数型,用'8'会默认启动类型转换,增加查询的开销。
?
4. 尽量减少使用正则表达式,尽量不使用通配符。

?

5. 使用关键字代替函数
?? 如:
?? select id from employee where UPPER(dept) like 'TECH_DB'? (错)
?? select id from employee where SUBSTR(dept,1,4)='TECH'????(错)
?? select id from employee where dept like 'TECH%'?????????(对)
?
6.不要在字段上用转换函数,尽量在常量上用
? 如:
? select id from employee where to_char(create_date,'yyyy-mm-dd')='2012-10-31'? (错)
? select id from employee where create_date=to_date('2012-10-31','yyyy-mm-dd')???(对)
?
7.不使用联接做查询
?如:select id from employee where first_name || last_name like 'Jo%'? (错)
?
8. 尽量避免前后都用通配符
? 如:
? select id from employee where dept like '%TECH%' (错)
? select id from employee where dept like 'TECH%' (对)

?

9. 判断条件顺序
? 如:
? select id from employee where creat_date-30>to_date('2012-10-31','yyyy-mm-dd')?? (错)
??? select id from employee where creat_date >to_date('2012-10-31','yyyy-mm-dd')+30?? (对)
???
10. 尽量使用exists而非in
?当然这个也要根据记录的情况来定用exists还是用in, 通常的情况是用exists
?select id from employee where salary in (select salary from emp_level where....)?? (错)???
?select id from employee where salary exists(select 'X' from emp_level where ....)?? (对)
?
11. 使用not exists 而非not in
??? 和上面的类似
???
12. 减少查询表的记录数范围

?

13.正确使用索引
? 索引可以提高速度,一般来说,选择度越高,索引的效率越高。


14. 索引类型
??唯一索引,对于查询用到的字段,尽可能使用唯一索引。
??还有一些其他类型,如位图索引,在性别字段,只有男女的字段上用。

?

15. 在经常进行连接,但是没有指定为外键的列上建立索引

?

16. 在频繁进行排序会分组的列上建立索引,如经常做group by 或 order by 操作的字段。

?

17. 在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不建立索引。如性别列上只有男,女两个不同的值,就没必要建立索引(或建立位图索引)。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。

?

18. 在值比较少的字段做order by时,翻页会出现记录紊乱问题,要带上id字段一起做order by.

?

19. 不要使用空字符串进行查询
??? 如:
??? select id from employee where emp_name like '%%' (错)
???
20. 尽量对经常用作group by的关键字段做索引。

?

21. 正确使用表关联
??? 利用外连接替换效率十分低下的not in运算,大大提高运行速度。
??? 如:
??? select a.id from employee a where a.emp_no not in (select emp_no from employee1 where job ='SALE')? (错)
???
22. 使用临时表???
?? 在必要的情况下,为减少读取次数,可以使用经过索引的临时表加快速度。
?? 如:
?? select e.id from employee e ,dept d where e.dept_id=d.id and e.empno>1000 order by e.id?? (错)
??
?? select id,empno from employee into temp_empl where empno>1000 order by id
?? select m.id from temp_emp1 m,dept d where m.empno=d.id????? (对)
??
???
?
???
?对于大数据量sql语句性能优化更多的工作就交给dba去实践,我们程序员做好这些基本功就好了。

1 楼 gmawaje 21 小时前   往往在项目中,很多时用到了两表的查询,
就是你说的第七点。 2 楼 魔力猫咪 21 小时前   2并非不可以,只要结果集非常小,可以直接索引定位那么就没问题。
4按需求来。不是你想不用就不用的
6用函数有时没辙,这种情况下可以考虑函数索引
8同4
9标题错误,和判断顺序无关
10好好学习一下吧,不要传播错误观念了。
11同10
12写成驱动表比较好。
14请去学习索引
15干嘛你不指定外键。这里设计有问题。
22直接物化视图不好吗?临时表完了可就没了,每次这么大量写表数据就少了?

3 楼 xingkongxieyang 19 小时前   有多少公司是真正有dba这个角色的啊。 4 楼 rainsilence 18 小时前   看到第三条就想吐槽了。=数字,万一传进一个空字符串,直接报错了。为了程序健壮性考虑还是''吧 5 楼 netkiller.github.com 17 小时前   3.避免隐含的类型转换

select id from employee where emp_id='8'  (错)
select id from employee where emp_id=8    (对)

有些数据库中 emp_id=8 这样写,将不使用索引。
另外如果是sql 采用字符串拼接,易产生注入漏洞。。



8. 尽量避免前后都用通配符
  如:
  select id from employee where dept like '%TECH%' (错)
  select id from employee where dept like 'TECH%' (对)


前提是dept 字段作了索引,否则没有什么不同



会误导多少新手? 6 楼 HeDYn 16 小时前   rainsilence 写道看到第三条就想吐槽了。=数字,万一传进一个空字符串,直接报错了。为了程序健壮性考虑还是''吧

没看明白你说的,我想是你没看懂吧,emp_id 是数值型的,你传个空字符串进去不会报错? 7 楼 cywhoyi 6 小时前   其实我觉得能够分享不错的,就是多了原则,少了内嵌含义吧,比如在有索引字段上函数处理,会丢失索引效果,比如对于query cache,我觉得告诉新手原则同时,能否多剖析一点为何要这么干,可能吸收会更好。 8 楼 Navee 6 小时前   引用
8. 尽量避免前后都用通配符
  如:
  select id from employee where dept like '%TECH%' (错)
  select id from employee where dept like 'TECH%' (对)

小弟不才,求讲解· 9 楼 eworkflow 6 小时前   魔力猫咪 写道2并非不可以,只要结果集非常小,可以直接索引定位那么就没问题。
4按需求来。不是你想不用就不用的
6用函数有时没辙,这种情况下可以考虑函数索引
8同4
9标题错误,和判断顺序无关
10好好学习一下吧,不要传播错误观念了。
11同10
12写成驱动表比较好。
14请去学习索引
15干嘛你不指定外键。这里设计有问题。
22直接物化视图不好吗?临时表完了可就没了,每次这么大量写表数据就少了?


多谢这位兄弟指出,匆忙写了一下,在sql执行性能方面,没有绝对的优,都要根据当时的情况来选,换成dba的说法,就是看执行计划,调到最优的效果,也许记录变了,环境变了,过一阵又需要再调整。 10 楼 魔力猫咪 6 小时前   如果想要学习如何高效使用数据库,我推荐《SQL语言艺术》这本书。 11 楼 dj4kobe 5 小时前   魔力猫咪 写道如果想要学习如何高效使用数据库,我推荐《SQL语言艺术》这本书。
这本书是不错的。

另,我想问下第一条,假如要10个表关联查询,如果按第一条,那这个SQL语句的层级就是9层了,那会很难维护的。求解释 12 楼 iwangxiaodong 5 小时前   由于SQL横跨众多编程语言,确实需要严格规范,倘若SQL标准组织再推出一个SQL性能标准那就再好不过了! 13 楼 魔力猫咪 5 小时前   dj4kobe 写道魔力猫咪 写道如果想要学习如何高效使用数据库,我推荐《SQL语言艺术》这本书。
这本书是不错的。

另,我想问下第一条,假如要10个表关联查询,如果按第一条,那这个SQL语句的层级就是9层了,那会很难维护的。求解释
这条没太注意,其实也不正确,至少描述不正确。不是说先两个表关联成1个子查询,然后再和其他表关联去。那种写法才是脑残呢。
SQL关联查询的核心就是驱动表过滤能力要强。只有驱动表结果集小的情况下,其他的关联表才会使用索引,不然就是全表。和你关联多少个表其实问题不大。现在性能最大的问题就是绝大多数时候我们只需要1个统计结果,或者少数几条数据,结果却是几个几十个的全表查询。表数据小没变化,数据量一大,速度下降飞快。 14 楼 workflow 4 小时前   魔力猫咪 写道2并非不可以,只要结果集非常小,可以直接索引定位那么就没问题。
4按需求来。不是你想不用就不用的
6用函数有时没辙,这种情况下可以考虑函数索引
8同4
9标题错误,和判断顺序无关
10好好学习一下吧,不要传播错误观念了。
11同10
12写成驱动表比较好。
14请去学习索引
15干嘛你不指定外键。这里设计有问题。
22直接物化视图不好吗?临时表完了可就没了,每次这么大量写表数据就少了?


赞成 15 楼 raveh 2 小时前   workflow 写道魔力猫咪 写道2并非不可以,只要结果集非常小,可以直接索引定位那么就没问题。
4按需求来。不是你想不用就不用的
6用函数有时没辙,这种情况下可以考虑函数索引
8同4
9标题错误,和判断顺序无关
10好好学习一下吧,不要传播错误观念了。
11同10
12写成驱动表比较好。
14请去学习索引
15干嘛你不指定外键。这里设计有问题。
22直接物化视图不好吗?临时表完了可就没了,每次这么大量写表数据就少了?


赞成
+1
同时觉得楼主不应该用“对”“错”来判定。
16 楼 elgs 1 小时前   10好好学习一下吧,不要传播错误观念了。
11同10


10和11有什么不对?我的理解也是尽可能用exists而不要用in。
17 楼 elgs 1 小时前   魔力猫咪 写道
10好好学习一下吧,不要传播错误观念了。
11同10


10和11有什么不对?我的理解也是尽可能用exists而不要用in。 18 楼 loveuserzzz 37 分钟前   楼主,解释一下这个是什么原理:
select id from employee where dept like '%TECH%' (错)
  select id from employee where dept like 'TECH%' (对) 19 楼 fatzhen 16 分钟前   不说为什么,新手学到的很少,或者被误导
知道了为什么,其实很多都是一回事
建议新手还是学习索引和执行计划吧

热点排行