ylbtech-DB-MySQL:MySQL 语句性能优化
1.返回顶部
1、

MySQL概述
1.数据库设计 3范式
2.数据库分表分库---会员系统() 水平分割(分页如何查询)MyChar 、垂直
3.怎么定位慢查询
---------------------
数据库索引的优化、索引原理
SQL语句调优
数据库读写分离--MyChar
---------------------
分组 having
存储过程、触发器、函数
存储过程:写了一块sql语句,类似Java中方法,只需调用传参数,弊端:sql语句是写死的,不好灵活改变。
mysql(免费、开源)oracle(收费)
mysql 分页 limit 。oracle:rownum 伪列

MySQL优化方案
1.数据库设计要合理(3F)
2.添加索引(普通索引、主键索引、唯一索引、全文索引)底层:B-Tree和B+Tree 和二叉树算法一样,减少全表扫描
3.分表分库技术(取模分表、水平分割、垂直分割)
4.读写分离
5.存储过程
6.配置MySQL最大连接数 my.ini
7.mysql服务器升级
8.随时清理碎片化
9.sql语句调优 核心

数据库三大范式
数据库设计
什么是数据设计(减少冗余量、3F)
什么事数据库3范式
1F 原子约束 表示每列不可再分
   id  name     sex   address
  1   zhangsan  0    北京

是否保证原子(看业务)

2F 保证唯一,主键
   id orderNum(唯一) name     sex   address
  1  123              zhangsan  0    北京
  订单表中,是否用id作为订单号?不允许。
  项目内部rpc远程调用 大多数是使用id进行通讯的,给外部看的是orderNum,保证系统安全性。
 
  分布式系统解决并发生成订单号
  怎么保证抢票中,订单号不会重复生成?怎么保证订单的幂等性(幂等就是不重复)?
  提前将订单号生成号,存在redis中,需要是直接去redis中去取;分布式锁

3F 不要有冗余数据  classId  className重复,这个表只存classId即可
   id  name     sex   address  classId  className
  1   zhangsan  0    北京     1        一班
  2   lisi    0    北京     2        二班
  2   wangwu   0    北京     1        一班

从新建张表:
 classId  className
 1        一班
 2        二班
 
 注意:不一定完全要遵循第3F。

MySQL分库分表
什么时候分库:
    电商项目当中,将一个项目拆分,拆分成多个小项目,每个小的项目有自己单独的数据库,互不影响。--垂直分割。
  会员数据库、订单数据库、支付数据库

什么时候分表:
    水平分割,分表规则,根据业务需求。存放日志 根据年分表、手机号 根据前三位分表 136 135 135
  水平分割(取模算法)

user表  分成三张表 
  id  name   address
  1   张三   北京
  2   李四   北京
  3   王五   北京
  4   赵六   北京
  5   小明   北京
  6   小红   北京

怎样将6条数据存放在三张不同的表中,怎样非常均匀? 取模算法
  表: user0 user1 user2  
  第一条数据:1%3=1 ,放user1表。  
  第二条数据:2%3=2 ,放user2 表。   
  第三条数据:3%3=0 ,放user0表。依次类推

实现取模分表算法:三张表id不能自动增长,需要专门有一张表存放userId,给赋值过去。

水平分割取摸算法案例
好处:非常均匀的分配
怎样查在哪里表?找id为6在哪个表 6%3=0 在user0表找

Demo:

create table uuid(
 id int unsinged primary key auto_increment,
)engine=myisam charset utf8;

@Service
public class UserService{
 
 @Autowired
 private JdbcTemplate jdbcTemplate;

/**
  * 生成用户信息
  */
 public String regit(String name,String pwd){
  //1.生成userId
  String insertUuidSql="insert into uuid values (null)";
  // 这里一般用直接返回主键id,不用下面的查询
    jdbcTemplate.update(insertUuidSql);
  //select last_insert_id()表示查询最近的主键ID的意思
    Long userId = jdbcTemplate.queryForObject("select last_insert_id()",requiredType,Long.class);
  //2.存放具体哪张表中
  String tableName = "user"+userId%3;
  //3插入到具体表中
  String insertUserSql = "insert into "+tableName+" values("+userId+","+userName+","+pwd+")";
  System.out.println(insertUserSql);
  jdbcTemplate.update(insertUserSql);
  return "success";
 }

/**
  * 根据id查询
  */
 public String get(Long userId){
  //1.存放具体哪张表中
  String tableName = "user"+userId%3;
  String selectUserSql="select name from "+tableName+"where id="+userId;
  String name = jdbcTemplate.queryForObject(selectUserSql,String.class);
  return name;
 }
}

@RestController
public class UserController{

@Autowired
 private UserService userService;

@RequestMapping("/regit")
 public String regit(String name,String pwd){
   return userService.regit(name,pwd);
 }

@RequestMapping("/getUser")
 public String get(Long userId){
   return userService.get(userId);
 }
}

@SpringBootApplication
public class App{
 public static void main(String[] args) {
     SpringApplication.run(App.class,args);
  }
}

分表之后有什么缺点?
1.怎么分页查询
2.查询非常受限制,例如查性别男要查三张表
3.取模算法 如果表发生改变了,表要重新分,打乱了 使用阿里云RDS数据库

先主表存放所有数据 ,根据业务需求进行分表

如何定位慢查询

什么是慢查询?
MySQL默认慢查询是10秒,如果10秒没有响应回来就是慢查询,一般在生产环境设置为1秒

慢查询都会有日志存放
show status 命令

如何修改慢查询
--查询慢查询次数
show status like 'slow_queries';
--查询慢查询时间
show variables like 'long_query_time';
--修改慢查询时间
set long_query_time=1; 表示修改慢查询时间为1秒

如何将慢查询定位到日志中
在默认情况下,MySQL不会记录慢查询,需要在启动MySQL的时候,指定记录慢查询才可以。

编辑配置文件/etc/my.cnf加入如下内容
[mysqld]
slow_query_log = ON
slow_query_log_file = /var/lib/mysql/test-10-226-slow.log
long_query_time = 1

修改配置后重启mysql
systemctl restart mysqld
mysql -uroot -p

MySQL索引概述

为什么要索引?提高查询效率
为什么索引能够提高查询效率--索引实现原理 折半查找

索引分类:
主键索引 -- primary key
添加主键索引方式:
1. 创建表的时候添加:id int unsinged primary key auto_increment,
2. 如果创建表的时候没有添加:alert table 表名 add primary key (列名);

删除主键索引:alert table 表名 drop primary key;

C:\ProgramData\MySQL\MySQL Server 5.6\data\test 下:

*.frm 表结构文件
*.MYD 数据结构文件
*.MYI 索引文件

唯一索引
组合索引
全文索引
普通索引

索引底层实现原理

索引底层采用b-tree 折半查找又叫二分查找

没有索引是全表扫描--索引 减少全表扫描

索引 b-tree 首先生成索引文件

索引有什么缺点?增加、删除 索引文件也需要更新

普通索引与唯一索引

唯一索引:关键字unique
create table 表名称(
 id int primary key auto_increment, // 主键索引
 name varchar(32) unique;      //唯一索引
)

注意:unique字段可以为null,并可以有多个null,但是如果有具体内容,则不能重复。
唯一索引用的不多,被主键索引代替了。

普通索引:
create table 表名(
 id int unsigned,
 name varchar(32)
)

创建普通索引:creat index 索引名 on 表 (列1,列2);

creat index index_aaa on aaa (name);

--执行计划 查看有没有使用索引
explain select * from aaa where name="zhangsan";
查询出type为ref表示使用索引 all是全表扫描

全文索引:

create table aaa(
 id int primary key,
 title varchar(200),
 body TEXT,
 FULLTEXT(title,body)  // 创建全文索引
)engine = innodb;

模糊查询:select * from aaa where body like '%张%' ; 错误用法,索引不会生效

使用执行计划查看是否使用索引:
explain select * from aaa where body like '%张%' ;

使用索引查询: select * from aaa where match(title,body) against('张')

使用执行计划查看是否使用索引:
explain select * from aaa where match(title,body) against('张')

使用全文索引的时候:
不要like
企业实际中不会采用表的全文索引。全文索引有非常大的缺点,InnoDB(数据库存储引擎)中不支持全文索引

SQL语句优化方案总结

索引优缺点:
优点:提高程序效率
缺点:增加、删除慢,索引文件需要更新,增加内存

什么字段适合加索引?
查询次数比较多,值有非常多的不同

建立索引场景:
建立索引的时候,where条件需要查询的,并且值非常多的不同的。唯一几个值(sex:0,1),不需要建立索引。

索引注意事项,sql调优部分:

--创建主键索引
alert talbe 表名 add primary key (列名);
--创建组合索引文件
alert table 表名 add index my_ind(列1,列2);

注意:
1.对于创建的多列索引,如果不使用第一部分,则不会创建索引
explain select * from 表名 where 列1 = 'aaa';  -- 使用索引
explain select * from 表名 where 列2 = 'bbb';  -- 使用全表扫描

2.使用索引的时候,不要使用like'%%' ,这样会全表扫描,使用like,开头不要%
explain select * from 表名 where 列1 like '%aaa%';  -- 使用全表扫描
explain select * from 表名 where 列1 like 'aaa%';   -- 使用索引

3.使用or,条件都必须加索引,只要有一个条件不加索引,就会全表扫描
explain select * from 表名 where 列1 = 'aaa' or 列3 ='ccc';  -- 使用索引

4.判断是否为null ,使用is null 不要=null
5.使用group by 分组不会采用索引,会全表扫描
explain select * from 表名 group by 列2;
6.分组需要效率高,禁止排序(分组默认排序)
explain select * from 表名 group by 列2 order by null ;
7. select * from aaa where userId>=100 和 select * from aaa where userId>100 哪个效率高
不要使用大于等于,会判断两次全表扫描

8. in和not in 加上索引后也不会使用索引,能用between就不要用in
9.查询量非常大时,采用缓存、分表、分页

MySQL存储引擎区别

MySQL存储引擎:innodb/ myisam/ memory

主流:innodb 支持事务机制

innodb与myisam区别:
批量添加--myisam效率高
innodb--事务机制非常安全

锁机制:
myisam是表锁
innodb是行锁,不会影响整个表

数据结构:
myisam 支持全文检索,一般不用数据库自带的全文检索。

都支持b-tree数据结构

索引缓存 都支持。

Myisam注意事项

创建myisam引擎表结构:
create table ccc(id int,name varchar(32))engine=myisam;
添加数据:
insert into ccc values(1,'a');
insert into ccc values(2,'b');
insert into ccc values(3,'b');
insert into ccc select id,name from ccc;

删除id为3的所有数据
delete from ccc where id = 3;

会发现:ccc.MYD文件大小没有改变,缺点:没有真正的删除,删除后能够非常快的恢复过来

真要删除使用:optimize table ccc; 表示对myisam进行整理,清了碎片化。
企业实际中是不会物理删除数据的,数据迁移

2、
2.返回顶部
 
3.返回顶部
 
4.返回顶部
 
5.返回顶部
 
 
6.返回顶部
 
作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

DB-MySQL:MySQL 语句性能优化的更多相关文章

  1. 深入MySQL(四):MySQL的SQL查询语句性能优化概述

    关于SQL查询语句的优化,有一些一般的优化步骤,本节就介绍一下通用的优化步骤. 一条查询语句是如何执行的 首先,我们如果要明白一条查询语句所运行的过程,这样我们才能针对过程去进行优化. 参考我之前画的 ...

  2. 52 条 SQL 语句性能优化策略,建议收藏

    本文会提到 52 条 SQL 语句性能优化策略. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引. 2.应尽量避免在where子句中对字段进行nul ...

  3. 关于Oracle-SQL语句性能优化

    Oracle-Sql语句性能优化 相信许多从事几年的开发人员都有过一些经验,相对于刚出来的毕业生而言,对于同种操作sql结果,他们的代码性能会更高一些.虽然本人还是个实习生,在这还是写写自己     ...

  4. Oracle SQL语句性能优化方法大全

    Oracle SQL语句性能优化方法大全 下面列举一些工作中常常会碰到的Oracle的SQL语句优化方法: 1.SQL语句尽量用大写的: 因为oracle总是先解析SQL语句,把小写的字母转换成大写的 ...

  5. MySQL学习笔记:select语句性能优化建议

    关于SQL中select性能优化有以下建议,仅当笔记记录. 1.检查索引:where.join部分字段都该加上索引 2.限制工作数据集的大小:利用where字句过滤 3.只选择需要的字段:减少IO开销 ...

  6. MySQL系列:性能优化

    1. 优化简介 MySQL性能优化包括:查询优化.数据库结构优化.MySQL服务器优化等. 2. 查询优化 2.1 分析查询语句 MySQL提供EXPLAIN和DESCRIBE,用来分析查询语句. E ...

  7. MySQL问题定位-性能优化之我见

    前言 首先任何一个数据库不是独立存在的,也不是凭空想象决定出来的. 数据库的架构离不开应用的场景.所以,为了解决某些深入的问题,首先你得掌握数据库的原理与架构.原理掌握得越深入,越能帮助你定位复杂与隐 ...

  8. MySQL 基础及性能优化工具

    数据库,用户及权限 常用用户管理操作 # 创建本地用户 abc create user abc@localhost # 创建内网能够访问的用户 abc create user abc@'192.168 ...

  9. mysql配置以及性能优化(转)

    MySQL配置文件my.cnf中文详解,附mysql性能优化方法分享 ================================================================= ...

随机推荐

  1. mybatis使用generator自己主动生成代码时的类型转换

    使用mybatis的generator自己主动生成代码,可是oracle数据库中number(6,2)总是自己主动转成BigDecimal.我想要转成的是float类型 这样就写了一个类型转换器,须要 ...

  2. jquery 弹窗插件 layer

    jquery 弹窗插件 layer 官网:http://sentsin.com/jquery/layer/ 1 <!DOCTYPE html PUBLIC "-//W3C//DTD H ...

  3. Oracle 位图索引

    内容简介: 1.位图索引 1.1位图索引使用注意事项; 1.2 使用位图索引; 1.3 位图索引对DML操作的影响; 2.位图连接索引 2.1 明确需求后使用位图索引; 2.1创建位图连接索引的注意事 ...

  4. checkbox复选框和div click事件重叠,点击div后复选框也被选中,同时改变div颜色,否则则不选中

     checkbox复选框和div click事件重叠,点击div后复选框也被选中,同时改变div颜色,否则则不选中 <!DOCTYPE html> <html lang=" ...

  5. Noip蒟蒻专用模板

    目录 模板 数论 线性筛素数 线性筛欧拉 裴蜀定理 卢卡斯定理 矩阵快速幂 逆元 高斯消元 图论 割点 最小生成树 倍增 SPFA 负环 堆优化迪杰斯特拉 匈牙利 数据结构 树状数组 ST表 线段树 ...

  6. centos 出现的问题

    1.DNS问题,导致yum没得源 echo "nameserver 8.8.8.8">>/etc/resolv.conf 2.CentOS 7最小化安装后找不到‘ifc ...

  7. LA 3635 Pie

    题意:给出n个圆,分给n+1个人,求每个人最多能够得到多大面积的圆 二分每个人得到的圆的面积 #include<iostream> #include<cstdio> #incl ...

  8. ZBrush中物体的显示与隐藏

    在ZBrush®中除了遮罩功能可以对局部网格进行编辑外,通过显示和隐藏局部网格也可以对局部进行控制.选择网格的控制都是手动操作,在软件中并没有相应的命令进行操作.选择局部网格的工作原理也很简单,即被选 ...

  9. 从源码中查看当前android版本

    从文件build/core/version_defaults.mk查找PLATFORM_VERSION例如:PLATFORM_VERSION.OPM1 := 8.1.0

  10. POST和GET详解

    GET和POST Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上 ...