Mysql索引

前言

索引是为了加快表中数据行的检索而创建的一种分散存储的数据结构。
索引不是越多越好,要合理的创建合适的索引。因为索引的数据大小是表数据的80%左右的。
索引是存储在硬盘的。

索引数据结构的选择

查询效率比较高的数据结构是二叉树。所以索引选了二叉树的结构B+tree。下面是MySql的索引结构。
Mysql索引_第1张图片
MySql中的索引分为主键索引和辅助索引。
Innodb 中辅助索引的叶子结点指向的主键索引的关键字;
Myisam中辅助索引的叶子结点直接保存了数据,不用去主键索引中查询

索引的分类

索引的创建遵循一个原则,列的离散型越高,选择性就越好。
离散型的计算公式:count(distinct(col)):count(col)。

  • 主键索引(聚集索引)
    MySql中默认主键就是聚集索引,如果不指定主键的话,Mysql内部会创建一个隐藏的聚集索引。
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
  • 唯一索引
    唯一索引要求该字段的值是唯一的
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
  • 普通索引
ALTER TABLE `table_name` ADD INDEX IndexName(`column`(length))
  • 全文索引
ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 
  • 联合索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

索引遵循最左匹配原则,也就是说对索引中的关键字进行计算(对比),一定是从走到右依次进行,切不可跳过。

索引使用

最常用的SQL如下

Select * from users where name = ? ;
Select * from users where phoneNum = ? ;
Select * from users where name = ? and phoneNum = ?;

索引解决方法

ALTER TABLE `users` ADD INDEX idx_name ( `name` )
ALTER TABLE `users` ADD INDEX idx_name ( `phoneNum` )
ALTER TABLE `users` ADD INDEX idx_name ( `name` ,`phoneNum` )

第一个索引是多余的索引。因为有最左原则,下面的联合索引可以实现对name索引。

Select id,name, phoneNum from users where name = ?;

name和phoneNum添加了索引,这条sql不回去查数据,通过索引返回数据

字段设计规范
  • 必须把字段定义为NOT NULL并且提供默认值
    NULL的列使索引、索引统计、值都比较复杂,对MySql来说更难优化
  • 禁止使用TEXT、BLOB类型
    会占用很大的磁盘和内存空间,非必要的大量的大字段查询会淘汰掉热数据,导致内存命中率急剧降低,影响数据库性能
  • 禁止使用小数存储货币
    小数容易导致钱对不上
  • 必须使用VARCHAR(20)存储手机号
    因为有有区号、varchar可以支持模糊查询
  • 禁止使用ENUM,采用TINYINT代替
索引规范
  • 单表索引建议控制在5个以内
  • 单索引字段数不允许超过5个
  • 禁止在更新十分频繁、区分度不高的属性上建立索引(散列性低)
  • 建立组合索引,必须把区分度高的字段放在前面
SQL使用规范
  • 禁止使用SELECT *,只获取必要的字段,需要显示说明列属性
  • 禁止使用INSERT INTO t_xxx VALUES(xxx),必须显示指定插入的列属性
  • 禁止使用属性隐式转换
    SELECT uid FROM t_user WHERE phone=13812345678 会导致全表扫描,而不
    能命中phone索引,phone是varcahr类型,需要添加引号
  • 禁止在WHERE条件的属性上使用函数或者表达式
    函数或者表达式会导致索引失效
SELECT uid FROM t_user WHERE from_unixtime(day)>='2017-02-15'会导致索引失效,导致全表扫描
正确使用:SELECT uid FROM t_user WHERE day>= unix_timestamp('2017-02-15
00:00:00')
  • 禁止负向查询,以及%开头的模糊查询
    • 负向查询条件:NOT、!=、<>、!<、!>、NOT IN、NOT LIKE等,会导致全表扫描
    • %开头的模糊查询,会导致全表扫描
  • 禁止大表使用JOIN查询,禁止大表使用子查询
  • 禁止使用OR条件,必须改为IN查询
    Mysql对in做了优化,会采用二叉法
  • 应用程序必须捕获SQL异常,并有相应处理

二叉树动态图

你可能感兴趣的:(SQL)