热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQL语句性能优化

MySQL概述1.数据库设计3范式2.数据库分表分库—会员系统()水平分割(分页如何查询)MyChar、垂直3.怎么定位慢查询———————数据库索引的优化、索引原理SQL语句



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中,需要是直接去resis中去取;分布式锁

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 命令

《MySQL语句性能优化》

如何修改慢查询
–查询慢查询次数
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 折半查找又叫二分查找

《MySQL语句性能优化》

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

索引 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_# on # (name);

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

全文索引:

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

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

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

使用索引查询: select * from # where match(title,body) against(‘张’)

使用执行计划查看是否使用索引:
explain select * from # 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 = ‘#’;  — 使用索引
explain select * from 表名 where 列2 = ‘bbb’;  — 使用全表扫描

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

3.使用or,条件都必须加索引,只要有一个条件不加索引,就会全表扫描
explain select * from 表名 where 列1 = ‘#’ 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 # where userId>=100 和 select * from # where userId>100 哪个效率高
不要使用大于等于,会判断两次全表扫描

8. in和notin 加上索引后也不会使用索引,能用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进行整理,清了碎片化。
企业实际中是不会物理删除数据的。数据迁移。


推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
author-avatar
潮爆啊--_317
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有