MySQL如何优化
表的设计合理化(符合3NF)
添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
SQL语句优化
分表技术(水平分割、垂直分割)
读写[写: update/delete/add]分离
存储过程 [模块化编程,可以提高速度]
对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]
mysql服务器硬件升级
定时的去清除不需要的数据,定时进行碎片整理(MyISAM)
水平拆分
上面谈到垂直切分只是把表按模块划分到不同数据库,但没有解决单表大数据量的问题,而水平切分就是要把一个表按照某种规则把数据划分到不同表或数据库里。例如像计费系统,通过按时间来划分表就比较合适,因为系统都是处理某一时间段的数据。而像SaaS应用,通过按用户维度来划分数据比较合适,因为用户与用户之间的隔离的,一般不存在处理多个用户数据的情况,简单的按user_id范围来水平切分
通俗理解:水平拆分行,行数据拆分到不同表中, 垂直拆分列,表数据拆分到不同表中
水平分割案例
思路:在大型电商系统中,每天的会员人数不断的增加。达到一定瓶颈后如何优化查询。
可能大家会想到索引,万一用户量达到上亿级别,如何进行优化呢?
使用水平分割拆分数据库表。
如何使用水平拆分数据库
使用水平分割拆分表,具体根据业务需求,有的按照注册时间、取摸、账号规则、年份等。
代码实战
项目结构图
package cn.zhiwei.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
/**
* 首先在数据库新建一个表存放自增id
* CREATE TABLE UUID(id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT)ENGINE=MYISAM CHARSET utf8;
* Created by 刘志威 on 2018/4/26.
*/
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
//进行分表,按数据库的主键id来分
public boolean markTable(String name){
// 1.先获取到 自定增长ID
String idInsertSQL = "INSERT INTO uuid VALUES (NULL);";
jdbcTemplate.update(idInsertSQL);
//得到了三个表共用一个自增id
Long insertId = jdbcTemplate.queryForObject("select last_insert_id()", Long.class);
//利用取模算法得到表名 表为user0 user1 user2
String table ="user" +insertId % 3;
//拼成添加的sql
String sql="insert into "+table+" values ('"+insertId+"','"+name+"');";
System.out.println("SQL:" + sql);
//执行添加方法
int update = jdbcTemplate.update(sql);
return update>0?true:false;
}
//分表查询
public String getUserName(Long id) {
//得到表名
String tableName = "user" + id % 3;
//拼接查询语句
String sql = "select name from " + tableName + " where id="+id;
System.out.println("SQL:" + sql);
String name = jdbcTemplate.queryForObject(sql, String.class);
return name;
}
}
package cn.zhiwei.controller;
import cn.zhiwei.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by 刘志威 on 2018/4/26.
*/
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/insertUser")
public Object insertUser(String name){
return userService.markTable(name);
}
@RequestMapping("/selectName")
public Object selectName(Long id){
return userService.getUserName(id);
}
}
package cn.zhiwei;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
* Created by 刘志威 on 2018/4/26.
*/
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
页面效果