SQL优化

-插入数据

批量插入:(一次尽量不超过1000条)

Insert into tb test values(1,'Tom'),(2,'cat'),(3, Jerny');

手动事务提交:

start transaction;

insert into tb_test values(1,'Tom'"),(2,'Cat'),(3, jerry');

insert into tb test values(4,'Tom'),(5,'Cat'),(6, jerry');

insert into tb test values(7,"Tom'),(8,'Cat'),(9,jerry');

commit;

主键顺序插入:

取决于mysql数据组织结构(后面会将主键优化),将插入主键按从小到大进行排列。

大批量数据插入:

如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MYSQL数据库提供的load指令进行插入。操作如下。

#客户端连接服务端时,加上参数--local-infile
mysql --local-infile -u root -p
#设置全局参数local infile为1,开启从本地加载文件导入数据的开关
select @@local infile;//查看是否开启0否1是
set global local infile =1;
#执行load指令将准备好的数据,加载到表结构中以","隔开字段。每一行通过"\n"分割
load data local infile '/root/sql1.log' into table `tb_user` fields terminated by ',' lines terminated by '\n';

注意:

load插入时最好也按照主键顺序插入,顺序插入性能会高于乱序插入。(为什么请看主键优化)

  • 主键优化

    在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)

页可以为空也可以填充一半,也可以填充100%。每个页包含了2-N行数据(如果一行数据多大,会行溢出),根据主键排列。

主键顺序插入示意图:

页分裂:

若主键乱序插入因xxxx可能会造成页分裂

页合并:

当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。

当页中删除的记录达到 MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。

知识小贴士:

MERGE_THRESHOLD:合并页的阈值,可以自己设置,在创建表或者创建索引时指定。

主键的设计原则:

1、满足业务需求的情况下,尽量降低主键的长度。

2、插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键

3、尽量不要使用UUID做主键或者是其他自然主键,如身份证号。

4、业务操作时,避免对主键的修改。

order by优化:

1、Using filesor:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sortbufer中完成排序操作,所有不是通过索引直

接返回排序结果的排序都叫 FileSort 排序。

2、Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。

#没有创建索引时,根据age,phone进行排序
explain select id,age,phone from tb_user order by age , phone,
#创建索引
create index idx_user_age_phone_aa on tb_user(age,phone),
#创建索引后,根据age,phone进行升序排序
explain select id,age,phone from tb_user order by age , phone,
#创建索引后,根据age,phone进行降序排序
explain select id,age,phone from tb_user order by age desc , phone desc ;

补充:

在创建索引时默认是升序的(从小到大)

但是也可以在创建是改变排序顺序:

create index idx_user_age_phone_ad on tb_user(age asc ,phone desc);

该方法创建的索引先通过年龄升序排序然后相同年龄的按手机号倒序排序。

总结:

根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。

尽量使用覆盖索引。

多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)>

如果不可避免的出现filesor,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k)。

如果超过排队缓冲区将会占用磁盘空间,会影响性能。

增加排队缓冲区
show variables like 'sort_buffer_size';//查看排队缓冲区大小
SET sort_buffer_size='2M';//设置排队缓冲区的大小为2M

group by优化:

#删除掉目前的联合索引
drop index idx_user pro_age_sta on tb_user;
#执行分组操作,根据profession字段分组
explain select profession , count(*) from tb_user group by profession;
#创建索引
create index idx_user_pro_age_sta on tb_user(profession,age,status);
#执行分组操作,根据profession字段分组
explain select profession, count(*) from tb_user group by profession ;
#执行分组操作,根据profession字段分组
explain select profession,count(*) from tb_user group by profession, age,

使用总结:

1、在分组操作时,可以通过索引来提高效率,

2、分组操作时,索引的使用也是满足最左前缀法则的。

limit分页 优化

一个常见又非常头疼的问题就是 limit 2000000,10,此时需要MYSQL排序前20000,10 记录,仅仅返回2000000-2000010

的记录,其他记录丢弃,查询排序的代价非常大。

优化方式:通过覆盖索引加子查询的方式

原SQL语句:缺点性能低  只需要查询10条数据其他数据进行丢弃,严重占用服务器的缓存、速度慢
select * from tb_sku limit 9000000,10; 优化后:
第一步:
select id from tb_sku order by id limit 9000000,10;//先查询需要的id, 并对其排序 最终sql
错误写法:原因-mysql不支持在in里面写limit
select * from tb_sku where id in (select id from th sku order by id limit 9000000,10);
正确写法:
select s.* from tb_sku s,(select id from tb sku order by id limit 9000000,10) a where s.id = a.id;

总结:

尽量避免使用大的偏移量,如limit 10000,10,因为这会导致MySQL扫描大量无用的行。

尽量结合where子句来过滤不需要的数据,以减少扫描的行数。

尽量使用有序的索引来避免文件排序,以提高查询效率。

count优化

MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count()的时候会直接返回这个数,效率很高,前提是没有where条件;

InnoDB引擎就麻烦了,它执行 count(
)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

count的工作原理:

count()是一个聚合函数,对于返回的结果集一行行判断,如果count函数的参数不是 NULL,累计值就加1否则不加,最后返回累计值。

count的用法以及优化思路:

count(主键):

InnoD8 引擎会遍历整张表,把每一行的 主键id 值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(主键不可能为null)

count(字段):

没有not null约束:InnoD8 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为nul,计数累加。

有not nul 约束:InnoD8 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。

count(1):

InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加。

count(*):

InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。

效率排序:

count(字段)<count(主键 id)<count(1)~ count(),所以尽量使用 count()。

update优化

mysql进阶-SQL优化篇的更多相关文章

  1. mysql的sql优化案例

    前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...

  2. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

  3. MySQL之SQL优化详解(二)

    目录 MySQL之SQL优化详解(二) 1. SQL的执行顺序 1.1 手写顺序 1.2 机读顺序 2. 七种join 3. 索引 3.1 索引初探 3.2 索引分类 3.3 建与不建 4. 性能分析 ...

  4. 基于MySQL 的 SQL 优化总结

    文章首发于我的个人博客,欢迎访问.https://blog.itzhouq.cn/mysql1 基于MySQL 的 SQL 优化总结 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 ...

  5. 【MySQL】SQL优化系列之 in与range 查询

    首先我们来说下in()这种方式的查询 在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效率,因为在一条索引里面,range字段后面的部分是不生效的. ...

  6. mysql索引sql优化方法、步骤和经验

    MySQL索引原理及慢查询优化 http://blog.jobbole.com/86594/ 细说mysql索引 https://www.cnblogs.com/chenshishuo/p/50300 ...

  7. (1.10)SQL优化——mysql 常见SQL优化

    (1.10)常用SQL优化 insert优化.order by 优化 1.insert 优化 2.order by 优化 [2.1]mysql排序方式: (1)索引扫描排序:通过有序索引扫描直接返回有 ...

  8. MySQL之SQL优化详解(一)

    目录 慢查询日志 1. 慢查询日志开启 2. 慢查询日志设置与查看 3.日志分析工具mysqldumpslow   序言: 在我面试很多人的过程中,很多人谈到SQL优化都头头是道,建索引,explai ...

  9. Mysql的SQL优化指北

    概述 在一次和技术大佬的聊天中被问到,平时我是怎么做Mysql的优化的?在这个问题上我只回答出了几点,感觉回答的不够完美,所以我打算整理一次SQL的优化问题. 要知道怎么优化首先要知道一条SQL是怎么 ...

  10. BATJ解决千万级别数据之MySQL 的 SQL 优化大总结

    引用 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 SQL 优化,不仅可以提高程序性能,还能减低线上故障的概率. 目前常用的 SQL 优化方式包括但不限于:业务层优化.SQL 逻 ...

随机推荐

  1. python性能分析器:line_profiler

    代码: import line_profiler import sys def test(): for i in range(0, 10): print( i**2 ) print("End ...

  2. conda报错、anconda报错:requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

    anconda报错,报错信息: requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 不能使用c ...

  3. 关于英语的语言规范问题——美式英语、英式英语和中式英语(Chinese English)到底哪个才是正宗 —— 中式英语才是英语世界的未来

    因为日常生成生活中总是会使用英语进行阅读.写作.学习和交流表达,由于小的时候是学传统正宗英语(英式英语),后来长大后因为美国实力强又开始学这个时候的正宗英语(美式英语),但是由于个人的能力问题(农村娃 ...

  4. 在oracle中将一行字符串拆分成多行

    例如,有如下一张表,表名为bk_test.插入了以下数据: CREATE TABLE BK_TESK(id varchar2(10),s varchar2(20)); insert into BK_T ...

  5. Ubuntu 安裝 RIME 輸入法

    RIME (Rime Input Method Engine,中州韻,中州韵)是一款很火的輸入法,虽然我目前还不知道它为什么火,不过先用用再说. 首先要吐槽一下 RIME 的说明文档,我感觉有点乱,第 ...

  6. 神经网络之卷积篇:详解池化层(Pooling layers)

    详解池化层 除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性,来看一下. 先举一个池化层的例子,然后再讨论池化层的必要性.假如输入是一个4×4矩阵,用到的 ...

  7. 【YashanDB知识库】数据变化率超过阈值统计信息失效

    [问题分类]性能优化 [关键字]统计信息 [问题描述] SQL --创建表结构 drop table t1; create table t1 (id int,name varchar2(200)); ...

  8. Splay/LCT 学习笔记

    唔,其实我不会 Splay,但是我会 LCT. 众所周知,会 LCT 和会 Splay 是两回事,因为 LCT 只需要旋至根即可. 到现在还是不会,但是先把 LCT 的 Splay 写一下吧. 自己复 ...

  9. Google – Reviews

    前言 继上一篇 Facebook – Reviews (Graph API) 后, 这篇继续介绍另一个 Reviews 大平台 Google Reviews. 想通过 API 获取 Google Re ...

  10. ASP.NET Core – Configuration & Options

    前言 之前就写过 Asp.net core 学习笔记 ( Configuration 配置 ) 只是有点乱, 这篇作为整理版. 项目中会有许许多多的 Config 要设定. 比较好的管理方式是把它们放 ...