系统优化总结(1)----MySql批处理

随着业务的蓬勃发展,我们的服务器日均访问量从年初的二三十万增加到现在的800万左右,对系统的原有架构和性能都是一个很大的挑战,所以最近对系统做了一次较大的优化升级来应对日益增长的服务器压力,对原来的业务逻辑和代码都做了重构,性能优化方面遵循了一个重要的原则:尽量减少请求与数据直接交互的次数和频度,其中一个重要的手段就是MySql批处理

这次重点对文章浏览模块进行了优化,这也是目前最大的流量入口,每天都有大量的文章浏览请求,每次有效浏览都对应一次用户加分操作和一次加分log记录,这样就会有频繁的数据库交互,也影响响应速度,所以加分和log记录在异步处理的基础上都进行了批处理。

1.MySql批量写入

MySQL批量写入语法是:

INSERT INTO table (field1,field2,field3) VALUES (“a”,”b”,”c”), (“a1”,”b1”,”c1”),(“a2”,”b2”,”c2”);

我们的数据层使用的mybatis框架,其动态sql语法对应的批处理是:

<insert id="batchInsert" parameterType="java.util.List">
   insert into
    <include refid="ScoreDetailTable"/>
    (user_id, score, type, archive,score_reason, created_at, updated_at,
     object_id,object_data,relation_user_id,relation_user_type)
    values
    <foreach collection="list" item="item" index="index" separator="," >
      (#{item.userId,typeHandler=idHandler},
       #{item.score,jdbcType=BIGINT},
       #{item.type,jdbcType=VARCHAR}, false,
       #{item.scoreReason,jdbcType=VARCHAR},now(), now(),
       #{item.objectId,typeHandler=idHandler},#{item.objectData,jdbcType=VARCHAR},
       #{item.relationUserId,typeHandler=idHandler},
       #{item.relationUserType,jdbcType=VARCHAR})
    </foreach>
</insert>

如上批量写入mysql可以大量减少与数据库的交互,减轻数据的压力,比之前逐个单独写入,批量写入时日志量(MySQL的binlog和innodb的事务让 日志)减少,降低了日志刷盘的数据量和频率,从而提高效率。同时也能减少SQL语句解析的次数,减少网络传输的IO,性能上有一定提升。

2.MySql批量删除

这里的批量删除是指多条件下的批量删除,比如你需要根据用户Id删除多个用户的有关记录,mybatis中的具体写法如下,挺简单:

<delete id="delete" parameterType="list">
<![CDATA[
delete user_log where fid in
]]>
<foreach collection="list" item="id"  open="(" separator="," close=")">
   #{id}
 </foreach>
 </delete>

这样就避免根据id逐个删除。

3.Mysql批量更新

这次优化中应用了两种批量更新的方法:一是: update table set field=x where id in(…),mybatis对应的写法实例如下:

<update id="batchUpdateRequstStatus"  parameterType="java.util.List">
 update vdlm_view_request_info set archive=true where id in
  <foreach collection="list" item="item" index="index"    open="(" separator="," close=")" >
    #{item.id,typeHandler=idHandler}
  </foreach>
</update>

第二种批量更新运用了case when语法,在给用户批量加分时需要根据用户ID和加分类型给不同的用户加不同的分值。mybatis中case when具体应用:

<update id="batchUpdateUserScore" parameterType="java.util.List">
 update vdlm_user_score
   <trim prefix="set" suffixOverrides=",">
      <trim prefix="total_score=case" suffix="end,">
         <foreach collection="userScoreList" item="item" index="index">
           when (user_id=#{item.userIdtypeHandler=idHandler} and
type=#{item.type,jdbcType=VARCHAR}) then total_score + #{item.totalScore,jdbcType=DECIMAL}
                </foreach>
                 else total_score
        </trim>
    </trim>
</update>

对应的SQL实例如下:

  update vdlm_user_score
  set total_score=case when (user_id=104007841 and
  type=‘totalscore‘) then
  total_score + 4
  when (user_id=105085333 and
  type=‘totalscore‘) then
  total_score + 5
  when (user_id=102013322 and
  type=‘totalscore‘) then
  total_score + 1
  else total_score end

4.MySql多条件批量查询统计

有这样一个需求:查询统计每天得分前三百名的用户和每个用户不同得分类型的分值及次数。使用case when ,一条sql就可以搞定:

SELECT user_id,
    sum( CASE WHEN type = ‘forward‘ or  type = ‘view‘ THEN score ELSE 0 END ) AS `totaolscore`,
    sum( CASE WHEN type = ‘forward‘ THEN score ELSE 0 END ) AS `forwardscore`,
    sum( CASE WHEN type = ‘view‘ THEN score ELSE 0 END ) AS `viewscore`,
    COUNT( CASE WHEN type = ‘forward‘ THEN 1 ELSE NULL END ) AS `forwardcount`,
    COUNT( CASE WHEN type = ‘view‘ THEN 1 ELSE NULL END ) AS `viewcount`
FROM vdlm_user_score_log WHERE  created_at>="2015-05-17 00:00:00" and created_at<"2015-05-17 23:59:59"
GROUP BY user_id ORDER BY `totaolscore` DESC LIMIT 300

本文链接http://blog.csdn.net/song19890528/article/details/46467243

时间: 2024-08-02 16:49:24

系统优化总结(1)----MySql批处理的相关文章

Windows中使用MySQL 批处理(五)

一.如何批量执行语句 1.将脚本存成一个脚本文件,比如company.sql 2.执行命令 mysql -h 主机 -u 用户名 -p <d:\dbdata\company.sql Enter password:****** 二.分页显示 mysql -h 主机 -u 用户名 -p <d:\dbdata\company.sql | more 三.捕获输出结果 1.输出的文件companyresult.out mysql -h 主机 -u 用户名 -p <d:\dbdata\company

MySQL批处理SQL语句

MySQL 支持批处理的模式执行一批SQL语句,下面的例子就是实验MySQL如何在windows下批处理执行SQL语句. create table test(id int,name varchar(20)); insert into test values(1,'watson'); batchfile.txt里包含下面的一些SQL 语句,此文件放在windows系统的c:/batchmysql/batchfile.txt insert into test select * from test;

java批处理、MySQL批处理

1 e: 2 cd MySQL\bin 3 mysql -uroot -proot 4 @pause MySQL批处理.bat 1 e: 2 cd JAVA\jdk1.8.0_77\bin 3 javac Hello.java 4 java Hello 5 @pause JAVA批处理.bat

mysql批处理/触发器/事务管理/存储过程

mysql里的批处理(sql语句) 格式: l mysql –u user –p < sql_file 表示从某个文件里执行sql语句 l mysql –u user –p < sql_file > out_file 表示从某个文件里执行,并将执行结果保存到out_file文件之中 举个例子: 小王每天早晨来之后,都需要查询班级共有多少人,还要查本学期共有几门课程,还要查询最近的考试成绩........需要做很多操作 sql.txt里  use pingtai;   //选择数据库 se

Mysql批处理

在批处理模式下使用mysql 在前面的章节中,你交互式地使用mysql输入查询并且查看结果.你也可以以批模式运行mysql.为了做到这些,把你想要运行的命令放在一个文件中,然后告诉mysql从文件读取它的输入: shell> mysql < batch-file 如果在Windows下运行mysql,并且文件中有一些可以造成问题的特殊字符,可以这样操作: C:\> mysql -e "source batch-file" 如果你需要在命令行上指定连接参数,命令应为:

下载配置MySql,快速启动MySql批处理,MySQL客户端软件SQL-Front的配置---ShinePans

首先,下载 sql 绿色版,:  http://yunpan.cn/cgERHhTtV8XGh  提取码 85bc 然后解压即可用, 安装目录下有bin文件夹,从里面的命令中启动服务 如下:   然后进入cmd ,首先输入 D: (我把解压包放在D盘了)  进入D盘根目录 然后输入 cd D:\mysql-5.0.22-win32\bin  这样就进入了安装包的根目录,(可以复制路径然后 cd 即可) 然后输入 命令   mysqld --console  就可以开启mysql 服务 如下: 由

java语言MySQL批处理

本质来讲就是使用Statement和PreStatement的addBatch()方法 代码 import java.sql.*; public class GetConnection{ public static void main(String[] args){ Access2Database adb=new Access2Database(); Connection conn=adb.getConn(); //transaction dealing PreparedStatement ps

MySQL之mysql客户端工作的批处理一些使用手法

通常我们会用mysql这个客户端程序来连接mysql库.这个通常是工作在交互式模式下的.如我们连接上mysql并执行如下操作: mysql -uroot -h127.0.0.1 -P3306 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 96 Server version: 5.7.17-enterprise-commercial-advanced-log MySQL En

MySQL通用优化技巧 | Ucloud运维在线微信群分享

MySQL通用优化技巧 | Ucloud运维在线微信群分享 2015-09-17 MySQL中文网 本文根据DevOps华南运维圈@UCloud微信群「大话运维」的嘉宾分享整理而成.「大话运维」将邀请业界运维前线技术专家作为分享嘉宾,分享技术趋势和技术实战,为运维朋友提供各种踩坑.躲坑.绕坑新技能. 嘉宾介绍 叶金荣Oracle MySQL ACE,国内最早的MySQL推广者.2006年创办国内首个MySQL专业技术网站 MySQL 中文网.资深MySQL专家,10余年MySQL经验,擅长Mys