给SQL语句传递无数参数,无需洪荒之力

 

如何传递数千个参数到一个SQL语句里?看数据库老兵的docker实践!...



周末碰到一个问题,应用需要传递数千个参数到一个SQL语句的in list,参数是从应用中来的,参数数量在几百/几千之间,在应用程序中拼一个很长的SQL,把所有参数都放到SQL正文中间是很多开发人员的做法,有时,因为对结果需要做group by/order之类的操作,传递数组参数显然比把结果集取回自己做更高效,但拼SQL很容易搞出很长的SQL,有没有其他的选择呢?

一种通用的方式是用临时表,MySQL可用的做法相对而言大致是最少的,让我们用Docker准备一个MySQL环境:

点击图片查看大图
需要注意的是,大多数现成的Docker images是基于最简化/最小化的概念打包的,和开发调试环境其实是有很多区别的:

点击图片查看大图
我们还需要一个JDK的环境:

点击图片查看大图
极简环境,大部分开发工作应该在开发环境完成

[rancher@rancher ~]$ docker cp Q3.java9980ba6fb8c2:/

[rancher@ranchermysql-connector-java-5.1.39]$ docker cp mysql-connector-java-5.1.39-bin.jar9980ba6fb8c2:/

进入容器,我们看到:

点击图片查看大图
传递的参数很多,但数据中能够满足条件的只有2。这里用到MySQL JDBC驱动一个属性,rewriteBatchedStatements=true,起的作用是什么呢?MySQL JDBC驱动实际对批操作支持很差,一般会把批操作改写成一个个的单个SQL执行,虽然仍然在传输层有着优化,大多数时候其实相比逐条SQL执行效率提升仍然不够,增加这个属性以后,会把insert into ... values()批操作改写成为insert into... values (),(),(),...,进一步提升插入操作性能。

MySQL和大多数数据库一样,临时表是每个session独立的,不同的session可以用相同的名字,可以有索引,但和ANSI SQL标准的create global temporary table不同的地方是,session结束后会被drop掉,使用时需要create,相对比较麻烦。但相比使用MySQL5.7.8以后新增的json来传递比较多的参数,还是比较简单可靠的,而且,没有数量限制,可以使用临时表上的索引来优化。其他数据库可以有XML/JSON等来把参数在应用中拼成一个XML/JSON数组一起传递,但JDBC4以后,JDBC驱动选择封装Array,能够批量传递一组参数用于类似的场景,但目前,使用上还是有点和数据库相关,比如,Oracle其实很早就支持传递数组参数到服务端,不过,需要用到一些Oracle的JDBC类和方法:

首先,我们需要根据参数的结构,定义类型,如果是scalar类型的参数数组,通常table of Varchar2是足够的,其他的数据类型参数,JDBC/数据库能够自动转换。

点击图片查看大图
但Oracle收购sun以后,成为了JAVA标准的事实主人,JDBC4也增加了Structure, Array等原来是Oracle JDBC驱动特有的类,不过,即使Oracle JDBC4的实现,目前也还是需要用到OracleConnection的createOracleArray的方法,其他数据库还没有实现对Structure,Array的支持,我们仍然需要一点不是数据库透明的用法:

点击图片查看大图
这里查询用到了Oracle另外一个用法,Table表函数,表函数用于产生一组记录,类似数据库表/查询结果集,而table表函数则可以作为连接SQL和PL/SQL的桥梁,能够把嵌套表/Varray等复杂的类表结构在SQL中作为表看待。有兴趣的可以尝试修改代码中的查询,传递数千个参数,运行一下看看。没有Oracle环境?不要紧,Docker可以帮你:

我的rancher环境曾经运行过同样的测试,并且,保留了运行环境,只需要重新启动JDK和11g express容器:

点击图片查看大图
最后,还是老套路!来个软广,招聘中间件管理岗工程师及MYSQL DBA,欢迎推荐或自荐。

岗位:系统管理工程师(中间件管理方向)岗位职责:

1. 负责devops体系规划和建设;

2. 负责应用系统中间件(WebSphere/Weblogic/Tomcat/JBoss)的部署、配置及架构规划;

3. 应用系统中间件性能调优、健康巡检、性能监控、问题处理等日常运维工作;

4. 负责公司测试环境和生产环境产品应用上线工作;

任职要求:

1.  计算机相关专业211大学本科及以上;

2.  熟悉linux操作系统,精通系统文件的配置和相应的操作命令;

3.  熟悉CVS、SVN等版本控制软件;

4.  熟悉常规中间件产品,包括WebSphere、WebLogic、JBoss和TOMCAT

5.  有良好的沟通能力和团队精神,做事认真踏实,态度端正,责任心强,能承受工作压力 ;

6.  有软件开发经验或互联网公司工作经验优先;



MySQL数据库管理DBA高级工程师

岗位需求人数:2人

有效期至:2016年10月

工作地点:北京

工作职责:

1)负责线上 MySQL 和 NoSQL 集群的架设、管理、维护、备份、扩容等基础工作。

2)负责公司数据库系统建设实施、现有系统优化改造方案制定、实施。

3)负责公司数据库系统变更方案,负责变更实施过程中问题解决。

4)负责公司数据库系统运行维护日常问题排查技术支持跟进及解决。

5)实施可靠的监控手段,保障各个数据系统高可用,保障数据安全、合理分配权限、信息脱敏保护等;。

6)7x24小时响应故障处理

任职要求:

1)国家统招本科及本科以上学历。3-4年以上工作经验。

2)精通linux,有中、大型系统数据库的运维经验、3年以上MySQL、mongoDB实际运维经验。

3)精通MySQL的开发,能够根据应用和优化、性能的需要指导开发团队编写sql以及存储过程等。

4)有大规模msql集群的部属、维护、管理和灾难恢复的经验,有亿级数据库表的使用经验,有分库分表的调整、优化、部属经验,包括创建集群、主从切换,任意添加节点,故障恢复,以及解决复制延迟的经验。

5)熟练掌握数据库性能优化的技巧,能够从全链路上定位性能瓶颈(网络、CPU、IO、操作系统等),提升数据库使用体验。

6)具备很好的沟通能力和团队精神,具有高度的责任心和主动性,能承受较大的工作压力。

7)有大型网站数据库和高并发量下数据库管理维护经验者优先。

欢迎推荐或自荐简历至  : hr-cloud@taikang.com


    关注 泰康云数据中心


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册