字段类型优先级

列:
整型date.time enum, char>varchar>blob, text
enum 约束,内部也是整形存储
char 定长, 考虑字符集和排序(校对集)
varchar 不定长,考虑字符集的转换和排序时的校对集,速度慢
text/Blob 无法使用内存临时表(排序只是在磁盘上进行)

性别:以utf8为例
char(1), 3个字长字节
enum(’男’,’女’)内部转换成数字来存储,多了一个转换过程
tinyint() 0 1 2 定长1一个字节

够用就行, 不要慷慨(smallint, varchar(N))

索引

提高排序速度
提高分组统计的速度

btree索引

btree索引常见的误区
1. 在where 条件常用的列上都加上索引, 在where cat_id =3 and price > 100
误区:cat_id 和 price 上都加上索引
错: 只能用到cat_id 或 price索引,因为是独立的索引, 同时只能用上一个
2. 在多列上建立索引,查询哪个列,索引都讲发挥作用
一般工作中使用联合索引比较多, 用到btree的左前缀原则
误:多列索引上,索引发挥作用,需要满足左前缀要求

hash索引

hash的劣势:

  • hash函数计算后的结果是随机的,如果是在磁盘上放置数据,以id为主键为例,随着id的增长,id对应的行,在磁盘上随机放置
  • 不能对范围查询进行优化 id > 4
  • 无法利用前缀索引
  • 排序也无法索引
  • 必须回行 通过索引拿到数据位置。必须回到表中取数据

聚簇索引

在MySQL中,MyISAM采用的是非聚簇索引的,InnoDB存储引擎是采用聚簇索引的
myisam 主索引和次索引都指向磁盘位置
innodb 次级索引指向主键的引用

innodb注意:
  1. 主键索引 既存储索引值, 又在叶子中存储行的数据
  2. 如果么有主键(primary key),则会使用unique key 做主键
  3. 如果么有unique, 则系统会生成一个内部的rowid做主键
  4. 在innodb中, 主键的索引结构中, 既存储了主键值,又存储了行数据,这种结构称为‘聚簇索引’

优势: 根据主键查询条目比较少时,不用回行(数据就在主键节点下)
劣势: 如果碰到不规则的数据时候会出现页分裂

  • 为什么会产生页分裂?

    这是因为聚簇索引采用的是平衡二叉树算法,而且每个节点都保存了该主键所对应行的数据,假设插入数据的主键是自增长的,那么根据二叉树算法会很快的把该数据添加到某个节点下,而其他的节点不用动;但是如果插入的是不规则的数据,那么每次插入都会改变二叉树之前的数据状态。从而导致了页分裂。

非聚簇索引

MYISAM是按列值与行号来组织索引的。它的叶子节点中保存的实际上是指向存放数据的物理块的指针
MYISAM引擎的索引文件(.MYI)和数据文件(.MYD)是相互独立的

覆盖索引

当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。

mysql的高性能优化

理想的索引

  1. 查询频繁
  2. 区分度高

索引碎片和维护

在数据的频繁的更改的过程中, 索引文件和数据文件会产生空洞,形成碎片
维护
1. 通过一个nop操作 (不产生对数据实质性影响的操作),来修改表
比如: 表的引擎是innodb, 可以alter table 222 engine innodb
2. optimize table 表名,也可以修复

sql语句优化

1.sql语句的时间用在哪儿?
答:等待时间, 执行时间
这两个时间并非孤立的, 如果单条语句执行的快了, 对其他语句的锁定的也少了如何来降低执行时间

  • sql语句的执行时间,花在哪儿?
    答:查找 沿着索引查找,慢者可能全表扫描
    取出 差到行后,把数据取出来

  • 何查询快?
    查询的快 联合索引的顺序, 区分度, 长度
    取的快, 索引覆盖
    传输的少,更少的行和列

2.切分查询: 按数据拆成多次
列: 插入10000行数据,每1000条为单位, 插件
分解查询: 按逻辑把多表连接查询分成多个简单的sql

3.sql语句的优化思路?
不查–> 少查–>高效的查

  • 不查:
    通过业务逻辑来计算
    比如论坛的注册会员数,我们可以根据前3个月统计的每天注册数,用程序来估算

  • 少查:尽量精准数据,少取行, 我们观察新闻网站,评论内容等,一般一次性取列表 10-30条左右

  • 必须要查, 尽量走在索引上查询行

explain

explain详解参考:https://www.cnblogs.com/liujingyuan789/p/6061188.html

mysql的高性能优化

id

查询的序号

select_type:

查询类型 例如:

SIMPLE简单查询 (不含子查询)
primary(含子查询或派生查询)
- subquery非from 子查询
- derived from型子查询
1. simple:
表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple,且只有一个。
2. primary:一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary。且只有一个。
3. subquery:除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery
4. dependent subquery:与dependent union类似,表示这个subquery的查询要受到外部表查询的影响。
5. derived:from字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套select。
6. union:union连接的两个select查询,第一个查询是dervied派生表,除了第一个表外,第二个以后的表select_type都是union。
7. dependent union:与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响
8. union result:包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null。

type

索引发挥的作用, 是扫描了一部分还是所有
依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL

possible_keys

可能用到的键

key

真正用的键

key_len

用于处理查询的索引长度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的列,这里不会计算进去。留意下这个列的值,算一下你的多列索引总长度就知道有没有使用到所有的列了。要注意,mysql的ICP特性使用到的索引不会计入其中。另外,key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中。

ref

多表联查时之间的引用关系

rows

估计本次查询出多少行

Extra

额外的信息

相关文章:

  • 2021-12-04
  • 2022-01-25
  • 2021-05-20
  • 2022-03-10
  • 2022-01-30
  • 2021-12-18
  • 2021-08-26
  • 2021-04-18
猜你喜欢
  • 2023-01-16
  • 2021-10-03
  • 2021-12-14
  • 2021-07-08
  • 2021-07-08
  • 2021-11-24
  • 2021-06-03
相关资源
相似解决方案