Swagger

Swagger

WebService提供了WSDL来描述提供的WS调用接口,还提供了其它工具来生成WS客户端代码。REST则可以使用Swagger规则来描述Restful接口,以及通过Swagger UI来测试Restful接口。

Swagger2是通过在接口上提供一系统注解来描述接口,而Swagger3则是通过一个swagger规范的json文件来描述。

Swagger使用指南
https://my.oschina.net/dlam/blog/808315
swagger2常用注解说明
https://blog.csdn.net/u014231523/article/details/76522486

Spring boot项目,使用maven打包包含本地jar
http://www.jianshu.com/p/4f88837945c9

swagger2markup

1.单独启动要输出文档的swagger服务。
2.在@Test中编写Swagger2MarkupConverter部分代码,或在pom.xml中配置。
3.运行mvn test,生成.adoc文件。
4.在Maven视图中,运行Plugins下的asciidoctor:process-asciidoc,生成html文件。
http://blog.didispace.com/swagger2markup-asciidoc/

进程管理工具

pm2

pm2 = P (rocess) M (anager)2,是可以用于生产环境的Nodejs的进程管理工具,它内置一个负载均衡,可以保证服务不会中断一直在线,并且提供0秒reload功能,还有其他一系列进程管理、监控功能。

pm2的安装和使用

npm install -g pm2
pm2 start app.js
pm2 startup, pm2 save 两条命令,用来保证服务器启动时,pm2管理的程序自动运行。
pm2 reload all
pm2 restart [id]
pm2 logs [id]
pm2 delete [id]
pm2 list
pm2 show [id] 或者 # pm2 info [id]  #查看进程详细信息

更多pm2常用的命令用法介绍
http://i5ting.github.io/node-deploy-practice/
http://www.111cn.net/sys/linux/120062.htm
http://www.pangjian.info/2016/12/02/deploy-nodejs-pm2-1/?utm_medium=referral

可以通过自定义启动文件,来管理jar包。创建xx.json,示例内容如下:

{
    "name": "cogrowth-api",
    "script": "java",
    "args": [
        "-Xms64m",
        "-Xmx512m",
        "-Dspring.profiles.active=pub",
        "-jar",
        "cogrowth-api-1.0.jar",
    ],
    "exec_interpreter": "",
    "exec_mode": "fork"
}
pm2 start xx.json

exec_interpreter: NodeJs解析器,本文不适用
exec_mode: 执行模式[cluster|fork]这个针对NodeJs应用的配置,非NodeJs应用统一fork
日志路径在~/.pm2/logs,stdout和stderr被分开存放,程序中的所有stdout和stderr都被收集方便查错。

Java开发工具类

Guava是一种基于开源的Java库,其中包含谷歌正在由他们很多项目使用的很多核心库。这个库是为了方便编码,并减少编码错误。这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方法。

生成PDF

freemarker

使用freemarker从模板+数据,生成html文件。

Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
        try {
            cfg.setClassForTemplateLoading(this.getClass(), "/static/");
            Template template=cfg.getTemplate("content.html");
            PrintWriter pw = new PrintWriter(new File(destPath));
            template.process(params, pw);
            pw.close();//关闭流
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }

生成Docker镜像的Dockerfile

FROM kenkoooo/ubuntu-openjdk8

RUN apt-get update \
    && apt-get install -y \
        curl \
        xfonts-base \
        xfonts-75dpi \
    && apt-get clean

#安装wkhtmltox(0.12.5版本没有生成目录,改用wkhtmltox_0.12.6版本)
#可以在https://builds.wkhtmltopdf.org/0.12.6-dev/中寻找对应系统的版本
RUN curl "https://builds.wkhtmltopdf.org/0.12.6-dev/wkhtmltox_0.12.6-0.20180618.3.dev.e6d6f54.xenial_amd64.deb" -L -o "wkhtmltopdf.deb"
RUN dpkg -i ./wkhtmltopdf.deb
RUN apt-get install -f
RUN rm -rf wkhtmlto*
ENV LANG C.UTF-8

#安装chrome-headless
RUN apt-get install --assume-yes libxss1 libappindicator1 libindicator7
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN apt install --assume-yes ./google-chrome*.deb
RUN rm -rf google-chrome*

#安装chrome-driver
#可以在线下载chromedriver_linux64.zip
#RUN wget https://chromedriver.storage.googleapis.com/73.0.3683.68/chromedriver_linux64.zip
#也可以拷贝下载好的chromedriver_linux64.zip
COPY chromedriver_linux64.zip .
RUN unzip chromedriver_linux64.zip
RUN cp chromedriver /usr/local/bin/chromedriver
RUN chmod 755 /usr/local/bin/chromedriver
RUN rm -rf chromedriver_linux64*

CPU架构

iPhone CPU架构

架构对应的设备:

 armv6 设备: iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch
 armv7 设备: iPhone3GS, iPhone4, iPhone4S;iPad, iPad2, iPad3(The New iPad), iPad mini;iPod Touch 3G, iPod Touch4
 armv7s设备: iPhone5, iPhone5C, iPad4(iPad with Retina Display)
 arm64 设备: iPhone5S, iPad Air, iPad mini2(iPad mini with Retina Display)

Android CPU架构

ABI:ApplicationBinary Interface 应用程序二进制接口,定义了二进制文件(尤其是.so文件),如何运行在相应的系统平台上,从使用的指令集、内存对齐到可用的系统函数库。
EABI:Embedded application binary interface 嵌入式应用二进制接口。

armeabi: 第5代、第6代的ARM处理器,是针对所有的arm cpu,只要支持arm的指令集就可以,早期的手机用的比较多。v7a,v8a是针对arm后来出的指令集版本制定的cpu如符合arm7指令集的cpu。
armeabi-v7a: 第7代及以上的 32位ARM 处理器,是针对有浮点运算或高级扩展功能的arm v7 cpu,2011年15月以后的生产的大部分Android设备都使用它.
arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一。
x86: 平板、模拟器用得比较多。
x86_64: 64位的平板。

项目包含总结

如果项目只包含了 armeabi,那么在所有Android设备都可以运行;
如果项目只包含了 armeabi-v7a,除armeabi架构的设备外都可以运行;
如果项目只包含了 x86,那么armeabi架构和armeabi-v7a的Android设备是无法运行的; 
如果同时包含了 armeabi, armeabi-v7a和x86,所有设备都可以运行,程序在运行的时候去加载不同平台对应的so,这是较为完美的一种解决方案,同时也会导致包变大。

例如,如果只想支持armeabi-v7a,需要在gradle中配置

    defaultConfig {
        ndk {
            abiFilters "armeabi-v7a"
        }
    }

默认情况下,打包后会自动生成armeabi 到 x86的所有文件夹。这就有可能导致一些x86的设备因为在x86文件夹下找不到so文件,而使应用崩溃。

Spring Cloud

Spring官方在spring boot的基础上,提供了一个名为Spring Cloud的开源项目,它是对Netflix开源组件进一步封装的一套云应用开发工具,一个非常优秀的服务治理框架。另一个非常优秀的服务治理框架 Dubbo。
Spring Cloud专注于提供良好的开箱即用经验的典型用例和可扩展性机制覆盖。

Netflix公司和Pivotal公司

Netflix是一家视频网站,该网站上的美剧应该是最火的。Netflix的微服务大规模的应用,在技术上毫无保留的把一整套微服务架构核心技术栈开源了出来,叫做Netflix OSS。Pivotal在Netflix开源的一整套核心技术产品线的同时,做了一系列的封装,就变成了Spring Cloud。Spring Cloud到现在为止不只有Netflix提供的方案可以集成,但Netflix是最成熟的。
Pivotal公司:Spring以及衍生框架、做缓存Redis、消息队列框架RabbitMQ、还有更牛的Greenplum,这些都是Pivotal公司的。还有Tomcat、Groovy里的一些顶级开发者,DevOps理论的提出者都在这个公司。Pivotal的Gemfire技术来解决尖峰高流量并发问题,才让12306刷票体验明显提升。

Spring Cloud微服务架构

在Spring Cloud微服务系统中,一种常见的负载均衡方式是:客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),然后再到具体的服务。服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在git仓库,方便开发人员随时改配置。

Spring Cloud微服务架构中的几个基础服务治理组件:

  • 服务注册中心:Eureka Server
  • 注册服务:Eureka Client
  • 发现服务:Discovery Client
  • 负载均衡:Load Balance、RestTemplate、Ribbon,Feign
  • 断路器:Hystrix,另外Feign自带断路器功能,断路打开后,可以避免连锁故障,fallback方法可以直接返回一个固定值。
    路由网关转发和过滤器:zuul,zuul还能过滤做一些安全验证,zuul默认和Ribbon结合实现了负载均衡的功能。Zuul是Netflix 提供的一个开源组件,致力于在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。
  • 分布式配置中心:spring cloud config,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。两个角色,config server config client。
  • 消息总线(Spring Cloud Bus):将分布式节点加入消息总线,利用轻量的消息代理(message broker 经纪人)使得应用程序可以高效地解耦通信过程。在众多的开源消息中间件产品中,当前版本的spring cloud bus仅支持两款中间件产品:rabbitmq和kafka两个binder,也可以自己写binder扩展。
  • Api gateway:
    微服务场景下,将细粒度的服务组合起来提供一个粗粒度的服务,所有请求都导入一个统一的入口,那么整个服务只需要暴露一个api,对外屏蔽了服务端的实现细节,也减少了客户端与服务器的网络调用次数。与业务关系并不大的通用处理逻辑可以从api gateway中剥离出来,api gateway仅仅负责服务的编排与结果的组装。这样对一些后端微服务进行了代理,避免了各个后端服务独立管理CORS和验证问题。
  • zuul静态路由配置规则:
    分布式系统中未使用注册服务时,service1的名称可更换,下面的配置中.path中的**会被添加到.url的后面。若不配置.url,可直接使用service1作为请求路径。

    zuul.routes.service1.url=http://localhost:8002/storage/
    zuul.routes.service1.path=/proxy/**
    
  • 动态路由
    动态路由需要达到可持久化配置和动态刷新的效果。即不仅要能满足从spring的配置文件properties加载路由信息,还需要从数据库加载配置。另外一点是,在容器启动后,能动态刷新内存中的路由信息,达到不停机维护路由信息的效果。

Cloud与微服务的关系

微服务是一种架构的理念,提出了微服务的设计原则,从理论为具体的技术落地提供了指导思想。
Spring Boot是一套快速配置脚手架,可以基于Spring Boot快速开发单个微服务。Spring Cloud是一个基于Spring Boot实现的服务治理工具包。Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架。Spring Boot/Cloud是微服务实践的最佳落地方案。

版本变化

  • Spring Cloud Finchley 在2018年 06 月 19 日正式发布,这次的重大发布主要带来了以下 4 项重大更新。
    (1)新增 Spring Cloud Gateway 组件
    Spring Cloud Gateway 是一个基于 Spring Webflux 和响应式 Netty 的下一代 API 网关,用来替换 Spring Cloud Netflix Zuul。它提供了更加简单的动态路由,以及针对每个路由的过滤器(如地址重写、断路器、添加/删除请求头、限流和安全等)。
    (2)新增 Spring Cloud Function 组件
    Spring Cloud Function 的主要功能如下:
    通过一系列函数推进业务逻辑的实现;
    将业务逻辑的开发生命周期从任何特定运行目标中分离,以便相同的代码可以作为一个 Web 端点、一个流处理器或一个任务来运行;
    支持一个跨 serverless providers 的统一编程模型,并拥有独立运行的能力(本地或 PaaS 平台);
    支持在 serverless providers 上面启用 Spring Boot 特性,如自动配置、依赖注入、指标等;
    (3)兼容 Spring Boot 2.0.x
    Finchley 版本是基于 Spring Boot 2.0.x 构建的,官方建议不要与 Spring Boot 1.5.x 及之前的版本一起工作。
    (4)最低支持 JDK 1.8
    JDK 门槛提高了,1.8 毕竟是现在的主流。
  • Camden。
  • Dalston将于 2018 年 12 月结束生命周期。
  • Edgware伴随着 Spring Boot 1.5.x 的结束而结束生命周期。

参考:
《Spring Cloud微服务实战》
http://blog.didispace.com/
http://blog.csdn.net/forezp/article/details/70148833
http://blog.csdn.net/u010066934/article/details/54232622

Spring Cloud 文档
http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_features

PiggyMetrics微服务编译运行解析
http://blog.csdn.net/nihaomanihao11/article/details/73822681
http://blog.csdn.net/rickiyeat/article/details/60792925

中小型互联网公司微服务实践-经验和教训
http://www.ityouknow.com/springcloud/2017/10/19/micro-service-practice.html

Spring Cloud各个微服务之间用http通信的效率的讨论

Spring cloud的http从几个方面可以优化:1、换成okhttp3。2、应用中不要做异步传输,防止异步等待,如果遇到异步场景,一定要利用好消息队列和缓存。3、如果http1.1,有些场景利用keep-alive,减少连接损耗。4、可以考虑尝试HTTP/2。替换原有的Jackson序列化为更快的或者更适合的序列化方式(例如fastJson,kryo);还有http连接池替换实现等都会有可观的性能提升。
一般场景下spring cloud的性能足以满足大多数需求,最终要看服务拆分是否合理和业务场景的实际需求。
rpc固然速度比http快,但是稳定性、数据传输的可靠性、熔断保护、更方便的链路监控和追踪,这时候HTTP的优势就体现了。
http传输内容上比rpc多了几十字节的头,对于一般都是几k到几十上百k的数据,几十个字节的头影响不大。
如果使用feign,会默认加keepalive也是长链接,就多了http的20字节报文头,但是开发效率却提升了几个档次。
目前很多大型项目多语言共存,http是最通用的协议,可以很好地解决跨语言跨平台兼容性。比如Dubbo协议,无法简单地实现跨语言。http交互只是协议比较重,但不会慢太多,追求单机极致性能的确可以考虑换协议。
微服务的一个重要理念就是水平扩展,慢这个问题通过业务设计还有多实例部署可以很好地提速。http协议很成熟,并且特点熟知:1.支持客户/服务器模式。2.简单快速。3.灵活。4.无连接。5.无状态。也是一个速度与开发成本还有兼容性相互妥协兼顾的结果。

https://www.zhihu.com/question/270355472

spring cloud与dubbo性能对比
http://www.cnblogs.com/chen110xi/p/6349580.html

eureka

eureka.client.register-with-eureka: 表示是否将自己注册到Eureka Server, 默认为true。 如果当前应用就是Eureka Server,则设为 false。
eureka.client.fetch-registry: 表示是否从Eureka Server获取注册信息,默认为true。如果这是一个单点的 Eureka Server,不需要同步其他节点的数据,可以设为false。
eureka.client.serviceUrl.defaultZone:在client端可以指定多个eureka服务,用逗号分隔。
https://www.jianshu.com/p/67fa6bbdbadf

在eureka中注册的服务要实现互通,前提是几台服务器的网络是通的。
主机服务程序在eureka中默认使用哈希值代替ip来作为识别码,可以配置eureka.instance.preferIpAddress=true来指定使用IP来作为识别码。

Mysql

mysql索引类型

btree索引:mysql中普遍使用B+Tree索引,但在实现方式上又分为聚簇索引和非聚簇索引。
hash索引:

聚簇索引和非聚簇索引

聚簇索引是指主索引文件和数据文件为同一份文件,聚簇索引主要用在Innodb存储引擎中。在该索引实现方式中B+Tree的叶子节点上的data就是数据本身,key为主键。
非聚簇索引是指B+Tree的叶子节点上的data并不是数据本身,而是数据存放的地址。主索引和辅助索引没啥区别,只是主索引中的key一定得是唯一的。主要用在MyISAM存储引擎中。非聚簇索引比聚簇索引多了一次读取数据的IO操作,所以查找性能上会差。

mysql表类型

1.InnoDB:
InnoDB,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。

支持事务,InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。
不加锁读取
支持外键
支持行锁
不支持FULLTEXT类型的索引
DELETE 表时,是一行一行的删除
InnoDB 把数据和索引存放在表空间里面
跨平台可直接拷贝使用
InnoDB中必须包含AUTO_INCREMENT类型字段的索引
表格很难被压缩
InnoDB的主键范围更大,最大是MyISAM的2倍
innodb属于索引组织表,有两种存储方式,共享表空间存储和多表空间存储,两种存储方式的表结构和myisam一样,以表名开头,扩展名是.frm。如果使用共享表空间,那么所有表的数据文件和索引文件都保存在一个表空间里,一个表空间可以有多个文件,通过innodb_data_file_path和innodb_data_home_dir参数设置共享表空间的位置和名字,一般共享表空间的名字叫ibdata1-n。如果使用多表空间,那么每个表都有一个表空间文件用于存储每个表的数据和索引,文件名以表名开头,以.ibd为扩展名。

2.MyISAM:
MyISAM:是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,不支持外键。如果执行大量的select,MyISAM比较适合。

不支持事务,回滚将造成不完全回滚,不具有原子性。
不支持外键
只支持表级锁,不支持行锁定,这样同一个表上的读锁和写锁是互斥的,MyISAM并发读写时如果等待队列中既有读请求又有写请求,默认写请求的优先级高,即使读请求先到,所以MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。因为MyISAM是锁表,所以某项读操作比较耗时会使其他写进程饿死。在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。

支持全文搜索,全文索引是指对char、varchar和text中的每个词(停用词除外)建立倒排序索引。MyISAM的全文索引其实没啥用,因为它不支持中文分词,必须由使用者分词后加入空格再写到数据表里,而且少于4个汉字的词会和停用词一样被忽略掉。
DELETE 表时,先drop表,然后重建表
MyISAM 表被存放在三个文件:frm 文件存放表格定义,数据文件是MYD (MYData) ,索引文件是MYI (MYIndex)引伸。
跨平台很难直接拷贝
MyISAM中可以使AUTO_INCREMENT类型字段建立联合索引
表格可以被压缩。
MyISAM支持GIS数据,InnoDB不支持。GIS数据是指空间数据对象:Point,Line,Polygon,Surface等。
MyISAM保存表的具体行数,在查询不带where时,直接返回保存的行数。所以没有where的count(*)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,count(*)时它直接从计数器中读;而InnoDB必须扫描全表。所以在InnoDB上执行count(*)时一般要伴随where,且where中要包含主键以外的索引列。这里特别强调“主键以外”,是因为InnoDB中primary index是和raw data存放在一起的,而secondary index则是单独存放,然后有个指针指向primary key。所以只是count(*)的话使用secondary index扫描更快,而primary key则主要在扫描索引同时要返回raw data时的作用较大。

3.对比选择:
MyISAM相对简单,在效率上要优于InnoDB。从效率上来看,如果系统读多写少,对原子性要求低,那么MyISAM最好的选择,且MyISAM恢复速度快,可直接用备份覆盖恢复。如果系统读少写多,尤其是高并发写入,InnoDB就是首选了。

MyISAM与InnoDB两者之间区别与选择,详细总结,性能对比
https://www.cnblogs.com/y-rong/p/8110596.html

mysql中不要用blob等大字段

在开发规范中,我们一般都是要求字段不要设置成blob这种大字段。原因是查询的时候效率问题。另外一个就是在插入量大的时候,生成的binlog太多,容易导致一些问题。线上就遇到了,1k多的插入,binlog狂写,磁盘干满了。

utf8mb4

MySQL在5.5.3之后增加了utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。
utf8mb4是utf8的超集,为了节省空间,一般情况下使用utf8就够了。

int(11)

int(n)中,n表示查询显示时的最小宽度,即最小的字符数。若不够最小长度,则前面补0。

Mysql调优

1.使用内置缓存
大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次,这些查询结果会被缓存。
对于像 NOW() 、RAND()、CURDATE()等SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以需要用一个变量来代替MySQL的函数,从而开启缓存。

2.使用 EXPLAIN 执行SELECT查询
使用 EXPLAIN 关键字可以打印出MySQL是如何处理SQL语句的,可以帮助分析查询语句或者表结构的性能瓶颈。
EXPLAIN 的查询结果还会告诉索引主键是被如何利用的、数据表是如何被搜索和排序的等等。
在SELECT语句(推荐挑选那个最复杂的,有多表联接的),把关键字EXPLAIN加到前面,可以使用phpmyadmin来执行。然后会看到一张表格。

3. 追加 LIMIT 1
查询表有时已经知道结果只会有一条结果,此时加上 LIMIT 1 可以增加性能。MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。
但是在用explain查询分析,显示limit 1加与不加,性能相同。是因为可能是使用了缓存吗?

4. 搜索字段建索引
索引并不一定是给主键或是唯一的字段,如果表中有某个字段经常用来做搜索,那么请为其建立索引。
有些搜索是不能使用正常的索引的。例如需要在一篇大的文章中搜索一个词时,如: “WHERE post_content LIKE ‘%apple%’”,索引是没有意义的。这可能需要使用MySQL全文索引或是自己做一个索引(比如搜索关键词、标签)。

5.使用 ENUM 代替 VARCHAR
ENUM 类型是非常快和紧凑的,实际上其保存的是 TINYINT,但其外表上显示为字符串。用这个字段类型来做选项列表变得相当的完美。比如“性别”,“国家”,“民族”,“状态”或“部门”字段,这些字段的取值是有限而且固定的,那么应该使用 ENUM 而不是 VARCHAR。

6.PROCEDURE ANALYSE() 结构建设
PROCEDURE ANALYSE() 会让 MySQL 帮助分析字段和其实际的数据,给出一些有用的建议。只有表中有实际的数据这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。
例如,如果你创建了一个 INT 字段作为你的主键,然而并没有太多的数据,那么,PROCEDURE ANALYSE()会建议你把这个字段的类型改成 MEDIUMINT 。或是你使用了一个 VARCHAR 字段,因为数据不多,你可能会得到一个让你把它改成 ENUM 的建议。但这些建议可能因为数据不够多而决策做得就不够准确。
在phpmyadmin里,你可以在查看表结构时,点击 “Propose table structure” 或“规则表结构”来查看这些建议,建议结果呈现在Optimal_fieldtype字段中。

7.字段尽量设置默认值
除非有特殊原因使用 NULL 值,否则应该总是让字段保持 NOT NULL。NULL需要额外的空间,并且在进行比较的时候,程序会更复杂。
下面摘自MySQL自己的文档:
“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”

MySQL 性能优化…经验分享
https://www.cnblogs.com/pengyunjing/p/6591660.html

sql语句优化

计算机存储空间分为:寄存器、高速缓存、内存、交换区(外部存储虚拟化)、硬盘以及其他的外部存储。从寄存器开始到硬盘读写速度是从快到慢依次递减。对于批量记录如果一条一条的连接数据库进行操作,耗费的时间非常恐怖。调优的环节之一,则是减少与数据库交互的次数,将多条查询、插入、更新合并为交互一次,也就是批操作。多次处理的操作交给主程序在内存中进行处理,内存中处理的速度要快上很多。

批量插入语句
将插入语句进行拼接,多条插入语句拼接成一条插入语句,与数据库交互一次执行一次。

//如果字符串太长,则需要配置下MYSQL,在mysql 命令行中运行 :
set global max_allowed_packet=2*1024*1024*10
//批量插入语句
insert into 表名(字段名1,字段名2)values(值a1,值b1), (值a2,值b2)

批量更新语句

UPDATE categories SET 
display_order = CASE id 
        WHEN 1 THEN 3 
        WHEN 2 THEN 4 
        WHEN 3 THEN 5 
END, 
title = CASE id 
        WHEN 1 THEN 'New Title 1'
        WHEN 2 THEN 'New Title 2'
        WHEN 3 THEN 'New Title 3'
END
WHERE id IN (1,2,3);

批量查询和删除

select * from tableName where id in (1,2,3,4) order by id
delete from tableName where id in(1,2,3,4,5,6)

sql语句取3000条记录

Oracle :
select * from table where rownum between 1 and 3000
select * from table rownum<3001
mysql:
select * from table limit 1 to 3000

插入记录隐藏列名时注意表结构中字段顺序

例如以下插入,是按字段顺序对应,不是按字段名对应。
insert into b_subuser_deleted_table SELECT * from b_subuser_table WHERE id=1