数据库优化-索引优化

优化原因

  • 性能低

  • 执行时间太长

  • 等待时间太长

  • SQL语句欠佳(连接查询)

  • 索引失效

  • 服务器参数设置不合理(缓冲、线程数)

Mysql表引擎

MySQL数据库支持多种存储引擎,每种引擎都有其自身的特点、优点和缺点。以下是几种常见的MySQL数据库引擎及其对应的优缺点:

InnoDB引擎

  • 优点:

    • 支持事务(ACID兼容):具有事务处理的能力,支持提交、回滚、并发控制和恢复能力。

    • 行级锁定:支持行级锁定,可提高并发性能。

    • 外键约束:支持外键约束,保证数据的完整性。

    • 支持热备份:可通过InnoDB的在线备份功能进行热备份。

  • 缺点:

    • 内存消耗较高:相对于其他引擎,InnoDB需要更多的内存和存储空间。

    • 性能开销:由于支持事务和行级锁定,性能开销相对较高。

MyISAM引擎

  • 优点:

    • 较低的内存消耗:相比InnoDB,MyISAM使用更少的内存和系统资源。

    • 速度较快:对于读密集型的应用,MyISAM通常具有更高的性能。

    • 全文搜索索引:支持全文搜索索引,适用于需要进行全文搜索的场景。

  • 缺点:

    • 不支持事务:不支持事务处理,因此在并发写入较高的情况下可能会出现数据不一致。

    • 表级锁定:只支持表级锁定,对于高并发写入的应用可能会导致性能瓶颈。

    • 不支持外键约束:不支持外键约束,容易导致数据完整性问题。

Memory引擎(也称为Heap引擎)

  • 优点:

    • 高速读写:数据存储在内存中,读写速度非常快。

    • 无磁盘I/O:由于数据完全存储在内存中,不涉及磁盘I/O操作,因此性能非常高。

    • 简单轻便:不需要进行复杂的磁盘操作,非常适合用作临时表或者缓存。

  • 缺点:

    • 数据易丢失:数据库重启或者服务器宕机时,数据将丢失,不适合持久化存储。

    • 内存限制:由于数据存储在内存中,受限于服务器内存大小,适用于小型数据集。

Archive引擎

  • 优点:

    • 压缩存储:数据存储采用压缩算法,占用空间较小。

    • 高速插入:适用于大量数据的批量插入操作,速度较快。

  • 缺点:

    • 读取性能较差:不支持索引,只能进行全表扫描,因此查询性能较低。

    • 不支持事务和外键:不支持事务处理和外键约束,数据完整性受限。

选择合适的存储引擎取决于应用的具体需求,如对事务支持的需求、并发读写的情况、数据量大小等。

主要使用

主要使用前两种

InnoDB(默认) :事务优先 (适合高并发操作;行锁)

MyISAM :性能优先 (表锁)

常用命令

查询数据库引擎: 支持哪些引擎?

show engines ;
image.png

查看当前使用的引擎

show variables like '%storage_engine%' ;
image.png

MYSQL逻辑分层

连接层 服务层 引擎层 存储层

image.png

SQL编写过程

select dinstinct  ..from  ..join ..on ..where ..group by ...having ..order by ..limit ..

SQL解析过程

这才是实际的sql解析过程,创建合适的复合索引应该按照这个顺序

from .. on.. join ..where ..group by ....having ...select dinstinct ..order by limit ...

索引介绍

定义与优劣势

  • 索引: 相当于书的目录

  • 索引: index是帮助MYSQL高效获取数据的数据结构。索引是数据结构(树:B+树(默认)、Hash树...)

    B+ B数 LAM

  • 弊端:

    1.索引本身很大, 可以存放在内存/硬盘(通常为 硬盘)

    2.索引不是所有情况均适用:

    a.少量数据

    b.频繁更新的字段

    c.很少使用的字段

    3.索引会降低增删改的效率(增删改 查)

  • 优势:

    1提高查询效率(降低IO使用率)

    2.降低CPU使用率

分类

  • 主键索引: 不能重复。id 不能是null

  • 唯一索引 :不能重复。id 可以是null

  • 单值索引 : 单列, age ;一个表可以多个单值索引,name。

  • 复合索引 :多个列构成的索引 (相当于 二级目录 : z: zhao) (name,age) (a,b,c,d,...,n)

注意主键索引和唯一索引的区别

注意:如果一个字段是primary key,则改字段默认就是 主键索引 不用创建

索引的CRUD

创建索引

方式一

create 索引类型 索引名 on 表(字段)

单值

create index dept_index on  tb(dept);

唯一

create unique index  name_index on tb(name) ;

复合索引

create index dept_name_index on tb(dept,name);
方式二

alter table 表名 索引类型 索引名(字段)

单值

alter table tb add index dept_index(dept) ;

唯一

alter table tb add unique index name_index(name);

复合索引

alter table tb add index dept_name_index(dept,name);

删除索引

drop index 索引名 on 表名 ;

   drop index name_index on tb ;

查询索引

下面一个linux环境下查看排版更好一点

show index from 表名 ;
show index from 表名 \G

分析SQL的执行计划

分析语句

Explain +sql

执行计划返回结果

  • id : 编号

  • select_type : 查询类型

  • table : 表

  • type : 类型

  • possible_keys : 预测用到的索引

  • key : 实际使用的索引

  • key_len : 实际使用索引的长度

  • ref : 表之间的引用

  • rows : 通过索引查询到的数据量

  • Extra : 额外的信息

image.png

id 编号

可以理解为sql的执行顺序

id值有相同,又有不同: id值越大越优先;id值相同,从上往下 顺序执行

准备sql

create table course
(
cid int(3),
cname varchar(20),
tid int(3)
);
create table teacher
(
tid int(3),
tname varchar(20),
tcid int(3)
);

create table teacherCard
(
tcid int(3),
tcdesc varchar(200)
);

insert into course values(1,'java',1);
insert into course values(2,'html',1);
insert into course values(3,'sql',2);
insert into course values(4,'web',3);

insert into teacher values(1,'tz',1);
insert into teacher values(2,'tw',2);
insert into teacher values(3,'tl',3);

insert into teacherCard values(1,'tzdesc') ;
insert into teacherCard values(2,'twdesc') ;
insert into teacherCard values(3,'tldesc') ;

查询教授SQL课程的老师的描述(desc)
通过不同的方式查询,分别id不同情况下,底层sql的执行顺序即id

EXPLAIN SELECT
    tc.tcdesc 
FROM
    teacherCard tc,
    course c,
    teacher t 
WHERE
    c.tid = t.tid 
    AND t.tcid = tc.tcid 
    AND c.cname = 'sql';
image.png
EXPLAIN SELECT
    tc.tcdesc 
FROM
    teacherCard tc 
WHERE
    tc.tcid = (
    SELECT
        t.tcid 
    FROM
        teacher t 
    WHERE
    t.tid = ( SELECT c.tid FROM course c WHERE c.cname = 'sql' ) );
image.png
EXPLAIN SELECT
    tc.tcdesc 
FROM
    teacherCard tc 
WHERE
    tc.tcid = (
    SELECT
        t.tcid 
    FROM
        teacher t 
    WHERE
    t.tid = ( SELECT c.tid FROM course c WHERE c.cname = 'sql' ) );
image.png

select_type 查询类型

  • PRIMARY: 包含子查询SQL中的 主查询 (最外层)

  • SUBQUERY: 包含子查询SQL中的 子查询 (非最外层)

  • SIMPLE: 简单查询(不包含子查询、union)

    在from子查询中, 如果有table1 union table2 ,则table1 就是derived,table2就是union

  • DERIVED: 衍生查询(使用到了临时表)

  • UNION: 上例

  • UNION RESULT : 告知开发人员,哪些表之间存在union查询

EXPLAIN SELECT
        cr.cname 
    FROM
        ( SELECT * FROM course WHERE tid = 1 UNION SELECT * FROM course WHERE tid = 2 ) cr;
image.png

type 索引类型、类型

重点 核心优化标准

system>const>eq_ref>ref>range>index>all 

其中:system,const只是理想情况;

调优目的 : 实际能达到 ref、range、 index就可以了

system

(忽略): 只有一条数据的系统表 ;或 衍生表只有一条数据的主查询

const

1.仅仅能查到一条数据的SQL

2.用于Primary key 或unique索引 (类型 与索引类型有关)

3.只有命中唯一索引或者主键索引

准备sql

create table test01
(
    tid int(3),
    tname varchar(20)
);

insert into test01 values(1,'a') ;
commit;

alter table test01 add constraint tid_pk primary key(tid) ;
explain select * from (select * from test01 )t where tid =1 ;
image.png
eq_ref

唯一性索引:对于每个索引键的查询,返回匹配唯一行数据(有且只有1个,不能多 、不能0)

alter table teacherCard add constraint pk_tcid primary key(tcid);
alter table teacher add constraint uk_tcid unique index(tcid) ;
explain select t.tcid from teacher t,teacherCard tc where t.tcid = tc.tcid ;
image.png

以上SQL,用到的索引是 t.tcid,即teacher表中的tcid字段; 如果teacher表的数据个数 和 连接查询的数据个数一致(都是3条数据),则有可能满足eq_ref级别;否则无法满足。

ref

非唯一性索引,对于每个索引键的查询,返回匹配的所有行(0,多)

准备数据:

 insert into teacher values(4,'tz',4) ;
 insert into teacherCard values(4,'tz222');

 ## 增加普通索引
 alter table teacher add index index_name (tname) ;

测试:

explain select * from teacher   where tname = 'tz';
image.png
range

检索指定范围的行 ,where后面是一个范围查询(between ,> < >=,

特殊:in有时候会失效 ,从而转为 无索引all)

alter table teacher add index tid_index (tid) ;
explain select t.* from teacher t where t.tid in (1,2) ;
image.png
explain select t.* from teacher t where t.tid <3 ;
image.png
index

-- tid 是索引, 只需要扫描索引表,不需要所有表中的所有数据

查询全部索引中数据

explain select tid from teacher ; 
image.png
all

-- cid不是索引,需要全表所有,即需要所有表中的所有数据

explain select cid from course ;

possible_keys 可能用到的索引

是一种预测,不准

key :实际使用到的索引

key_len :索引的长度

作用:用于判断复合索引是否被完全使用 (a,b,c)。

utf8:1个字符3个字节 gbk:1个字符2个字节 latin:1个字符1个字节

如果索引字段可以为Null,则会使用1个字节用于标识。

ref 表的关联字段

常量用const表示

rows: 被索引优化查询的数据个数

(实际通过索引而查询到的 数据个数)

Extra

优化的重点之一

using filesort

性能消耗大;需要“额外”的一次排序(查询) 。常见于 order by 语句中。

create table test02
(
    a1 char(3),
    a2 char(3),
    a3 char(3),
    index idx_a1(a1),
    index idx_a2(a2),
    index idx_a3(a3)
);
explain select * from test02 where a1 ='' order by a2 ; 
image.png
using temporary

性能损耗大 ,用到了临时表。一般出现在group by 语句中。

准备sql

干掉所有单键索引,创建复合索引。匹配最左原则

drop index idx_a1 on test02;
drop index idx_a2 on test02;
drop index idx_a3 on test02;

alter table test02 add index idx_a1_a2_a3 (a1,a2,a3) ;
explain select a1 from test02 where a1 in ('1','2','3') group by a1 ;

符合最左匹配查询 不会用到临时表

image.png

group by a2 用到了临时表

explain select a2 from test02 where a1 in ('1','2','3') group by a2 ; 
image.png
using where

(需要回表查询)

explain select a1,a3 from test02 where a3 = '' ;
image.png
using index

性能提升; 索引覆盖(覆盖索引)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容