SQL1

最近在学MySQL,这篇是第一篇,希望自己能够好好记笔记,方便以后的复习。

MYSQL逻辑分层

当我们执行一条命令时,比如

select * from student

数据库中的操作顺序如下:


数据库语句执行步骤

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

  • 连接层:只负责查询语句和数据库的连接
  • 服务层:提供用户使用接口,例如select、delete...同时还可以对sql语句进行优化
  • 引擎层:数据的存储方式(常用的有InnoDB(事务优先)、MyISAM(性能优先))
  • 存储层:最终执行后的数据在存储层
    查看当前使用了那些引擎

    指定数据库对象的引擎
    当有时候想要性能优先的时候,可以改掉默认的引擎
//修改默认的存储引擎,可以在创建的时候指定
 create table tb( id int(4) auto_increment, name varchar(5), dept varchar(5),primary key(id))ENGINE=MyISAM DEFAULT ChARSET=utf8;

SQL优化

为什么要优化:等待时间太长,执行时间太长,索引失效,服务器参数不合理(缓存区参数)
SQL:
编写过程:
select ... from ... join .... on where group by ... having ... order by limit
解析过程:
可能跟编写的过程不一样
from...on...join ... where ...group by... having...select ...
b.SQL优化
主要是优化索引,索引相当于书的目录,是高效查询数据的数据结构(树:B(默认)/Hash树...)

索引的例子

我们可以看到,右边是一个加了索引的树(当然这里是一个平衡二叉树,真实的环境是B树),加了索引树之后查询年龄只需要3次,不加就要5次,在千万级别的数据库中,这样可以节省大量的搜索时间。

  • 弊端:
    1 索引本身很大,可以存放在内存/硬盘
    2 少量数据,不需要索引
    3 频繁更新,每一次都要
    4 很少使用的字段,不需要加
    5 虽然可以增加检索效率,但是降低了增删改的效率
  • 优势:
    1 提高查询效率(降低IO使用率)
    2 降低CPU使用率:比如DESC,索引本身就排好序,不需要再排序了

BTree原理

数据都在叶节点里面,非叶子节点的数据只是为了分割数据


B树

索引

-分类
1 单值索引:单列的值,一个表可以有多个单值索引
2 唯一索引:不能重复,一般用id,值不能重复
3 复合索引:多个列构成,相当于二级目录(筛选两次,没有必要全部列都用)

创建索引

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

//根据部门创建一个单值索引
create index dept_index on tb(dept);
//给name加上唯一索引,假设name是唯一的
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);
//给name加上唯一索引,假设name是唯一的
alter table tb add unique index name_index(dept);
//复合索引
alter  table tb add index dept_name_index(dept,name);

DDL:create alter drop都是事务性语句,自动提交 不需要commit;

注意

  • 主键索引不能为null,唯一索引可以是null
  • primary就是默认的主键索引

删除索引

drop index name_index on tb;

查询索引

show index from table

SQL性能分析

  • sql执行计划:(explain 可以模拟sql优化器执行sql语句,让开发人员知道自己的sql执行状况)
  • 查询优化可能会干扰我们的优化
  • 查询执行计划
    id(编号) | select_type(查询类型) | table(表) | partitions | type(类型) | possible_keys(预测索引) | key | key_len | ref | rows | filtered | Extra

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 tearcherCard
(
tcid int(3),
tcdesc varchar(200)
);

查询样例
//查询课程编号为2或教师证编号为 3的老师信息
explain select t.* from teacher t, course c, tearcherCard tc where t.tid=c.tid and tc.tcid=t.tcid and (c.cid=2 or tc.tcid=3);

数据的顺序:t3-tc3-c4


explain

数据的顺序:tc3-t6-c4


自动优化

-为什么会有表的差异(笛卡尔积)
中间结果数据会变:数据小的表优先查询

id值不同的时候,越大越优先:查询sql课程的老师的描述

explain select tc.tcdesc from teacher t, course c, tearcherCard tc where t.tid=c.tid and tc.tcid=t.tcid and c.cname='sql';
//多表连接写成子查询形式(在嵌套子查询时先查最内存在查最外层)
  explain select tc.tcdesc from tearcherCard 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
  • id(编号) :有相同和不同,越大越优先,id值相同从上往下顺序执行(explain语句中)
  • select_type(查询类型):包含子查询sql中的子查询,PRIMARY、SUBQUERY、SIMPLE(最简单的,没有子查询,union),derived(衍生查询):from中只有一张表,在from子查询中(之前查询过来的)
  • type(类型):索引类型system>const>eq_ref>ref>range>index>all
    常用
    ref

    ref:不需要唯一性索引,数量是0或多
    range

range:检索一定范围内的数据,where里面的范围(between in(有时失效) > <=)


index

index:查询数据,查询全部索引里面的数据全部索引

all

all:查询所有数据全部数据

  • possible_keys(预测索引):预测用的索引
  • key:实际的索引
  • key_len:索引的长度,判断复合索引是否完全被使用
create table text(
name char(20) not null default ''
);
alter table text add column name1 char(20);
占用一个标识null
--加入复合索引,现根据name查,查不到,再根据另外一个name1查
alter table text add index index_name_name1(name,name1);
多级索引
varchar:1(null)+2(标识可变长)
  • ref:指明当前表参照的字段


    引用,一定要加上索引
  • rows:被索引优化查询的数据个数

  • Extra:
    1 using filesort--当前sql语句需要额外的一次排序
    复合索引,不能跨列,最佳左前缀
    create table A(
    a1 int,
    a2 int,
    a3 int,
    index idx_a1_a2_a3(a1,a2,a3),

);
查找的时候只能是select a1 order by a2...
不能是a2...a3或者a1...a3之类的,因为都跨列的,这样会出现using filesort情况

2 using temporary性能损耗比较大,用到了临时表,常见于group by语句中

根据a1查找,但是根据a2分组。避免:查询那些列就根据那个group by,本来游标了,但是还需要另外一张表查找

3 using index
会对possiblekey和key有影响,如果没有where,索引只出现在key中,否则possiblekey和key里面都有。
出现了using index表示性能提升了,索引覆盖。
原因:不读取源文件,只从索引文件中获取数据

不需要回表查询,只需要在索引里面查找就返回了

4 using where
需要回表查询
索引里面没有的,需要回到原表查询

select age ,name from .. where age=...

此语句必须要回到表格查询name,所以用where

5 possible where
永远不可能的
... where a1='x' and a2='y'

你可能感兴趣的:(SQL1)