procedure对大家来说并不陌生,如果要说服未接触过的开发同事应用一些过程到项目中,应该如何去说服呢,我最近遇到这样的问题,自己做了一些过程的优势的总结,性能上做了小测试,大家有什么妙招?
概念:存储在数据库当中的可以执行特定工作(查询和更新)的一组SQL代码的程序段
重复调用
具有特定功能的存储过程在被创建以后可以在程序中被多次调用,而且对存储过程进行修改对应用程序源代码毫无影响,既减少了开发人员的工作量同时提高了程序的可移植性,对存储过程中的sql的语句的优化不会带来代码的更改。
执行速度
存储过程是预编译的在首次运行一个存储过程时查询优化器对其进行分析优化并给出最终被存在系统表中的执行计划。而批处理的Transaction-SQL 语句在每次运行时都要进行编译和优化,应用程序中的sql语句数量很大,系统将消耗大量的资源在sql解析上面,而运用过程封装部分sql能有效缓解系统压力,并提高查询响应速度。(详见后续测试)
网络流量
一个事务需要用到10个sql,假设每个sql大小为1kb,单从流量上看,使用过程将节省9KB。同时还有交互过程中的网络流量,例如在一个事务性质的sql组合中,每条sql独立提交并获取结果数据做逻辑处理后传值(一个值,一个字符串,甚至一个表)给下一条sql。如果使用存储过程,sql之间的数据交互将在数据库内部进行,减少了大量的网络交互,同时减少的是整个事务的完成时间。
4安全
存储过程的运行时依据其创建者的权限。例如用户U不具备A表的任何权限,又需要为其提供部分的数据,可以赋予其调用过程P的权限,U通过存储过来访问数据,在过程中进行参数的审核,一定程度有效防止sql注入攻击,并可以控制其能够得到的数据内容。
5.事务
存储过程可结合事务执行。多sql在执行中mysql宕机或网络中断等原因,事务的回滚只能通过程序本身完成,由于程序大部分时间无法确定最后一次sql是否提交成功,回滚的可靠性低,将事务封装在过程中,数据库会有效地进行整个事务的提供和回滚操作。
二 测试
测试环境:
mysql Ver 14.14 Distrib 5.1.49, for debian-linux-gnu (x86_64) using readline6.1 2G
初始化:测试的3个表分别初始化50w条数据。
2.1 执行性能
业务场景:(完成select,update,delete,insert组合)
给出一个id,更新t1中此id对应数据,删除t2此id数据。向t2插入t1此id数据,返回t3表的数据。
Sqls:
sql0='flush query cache' 刷新查询缓存,保证测试数据有效
sql1='UPDATE t1 SET a_id=110 AND a_type=110 AND last_modified=NOW()WHERE id = %s'
sql2='DELETE FROM t2 WHERE id=%s'
sql3='INSERT INTO t2(guid,t_group,from_a_id,to_a_id) SELECT a_id,a_type,a_status,1FROM t1 WHERE id=%s'
sql4="SELECT MIN(t3.t_type),MAX(sys_id),COUNT(DISTINCT t2.`guid`)FROM t3 JOIN t2 ON t3.id=t2.id"
sql5='SELECT a.a_status,b.guid FROM t1 a,t2 b WHERE a.`a_id`=b.`guid`'
数据及分析:
Pro:存储过程 sql:多次sql 时间单位:s
序号
类别
开始时间
结束时间
时间消耗
随机id值
1
pro
1330742912.74
1330742918.3
5.56233501434
136369
sql
1330742929.56
1330742938.79
9.22886991501
53571
2
pro
1330743059.51
1330743065.2
5.69001603127
115445
sql
1330743046.83
1330743056.14
9.30604100227
143042
3
Pro
1330744056.55
1330744062.16
5.61571311951
68169
Sql
1330743738.2
1330743747.48
9.28886985779
144629
4
Pro
1330744123.48
1330744129.07
5.59134888649
69447
Sql
1330744157.11
1330744166.36
9.24880003929
14114
5
Pro
1330744196.59
1330744202.26
5.67109799385
55165
sql
1330744211.09
1330744220.46
9.36547088623
80620
平均值:sql 9.28761s pro:5.626102s
分析:
存储过程中的sql在编译时mysql会保存优化后的执行计划,所以调用时不需要进行sql解析和优化。
多次sql执行,需要对每一个sql语句进行解析和优化,如果sql语句量增加,系统将消耗大量资源在解析和优化上面,降低数据库整体性能。