Mysql优化

之前小公司数据量比较小,没有积累相关的经验,面试了个大公司被问尿了。

问题:用没用过索引?有没有数据库优化经验?

先从索引的原理开始看起,索引调优属于结构调优。

优质文章传送门:http://blog.codinglabs.org/articles/theory-of-mysql-index.html

我做下自己的重点总结:

1.myISAM引擎和InnoDB都使用B+Tree结构的索引。

2.B+Tree叶结点存储数据并指向相邻的叶结点方便范围查找。

3.myISAM的B+树叶结点存储的是数据地址,顾称为非聚集索引。

4.InnoDB的B+树叶节点直接存储的是数据,顾称为聚集索引。

5.InnoDB的要求表拥有唯一的主键,没有指明则找表内唯一性列,如果找不到就生成一个隐含字段,6字节,长整型。

6.InnoDB的辅助索引存储的是主键的值。

7.索引会增加查询效率降低存储效率,因为要维护索引,故加索引要适当。

了解到基本原理可以总结出几条优化建议:

1.主键的单调性,主键随机生成会导致维护B+树频繁的分裂调整,降低性能。

2.所有的辅助索引都会引用主键,所以主键太长会使辅助索引过大。

使用Explain 解析SQL语句:

参考博客传送门:http://blog.csdn.net/zhuxineli/article/details/14455029

 

看了很多sql优化的帖子,对于相同的理论有的说yes有的说no,还是直接看书吧。

以下摘自<高性能MySQL>

结构优化:

  • 更小通常更好,使用正好能存储和表示数据的最小类型,小的数据使用更少的磁盘空间、内存缓存,需要的CPU周期越小。
  • 简单就好,越简单的类型需要的cpu周期越小,比如比较整数代价小于比较字符串,这个大家都懂,尽量少用字符串。
  • 尽量避免使用NULL,如果需要NULL最好初始值设为0,或特殊字符串,Mysql难以优化可空列的查询,使索引和索引统计和值更加复杂。可空列需要占用额外的存储空间(- -?)当可空列被索引时,每条记录都需要一个额外的字节。但是null到not null 性能提升很小。

1.整数

  tinyint ,smallint ,mediumint,int ,bigint  分别占用8,16,24,32,64   范围-2(n-1)次~2(n-1)-1

  整数有个signed 和unsigned   ,unsigned会使整数的范围变为0~255,因为把符号位也算进去了。

  定义字宽int(1) 和int(10)并无存储上的区别,只是某些客户端上显示的位数。

2.实数

  decimal 尽量少用,会产生额外的存储空间和计算开销,尽量使用整数存储金额。

3.字符串

  varchar 可变长度,比固定长度的占用更少的存储空间,对性能是有帮助的,会用1~2字节保存列的最大长度,小于等于255(varchar(255))时是一个字节,大于255时(varchar(1000))用两个字节。

  varchar(1) 表示可以存储一个字符 :可以是a,可以是1,可以是一。这是我一直困惑的,也是傻,一试就知道了。

  ps:慷慨是不明智的,存储"hello" varchar(5),varchar(100)虽然占用的存储空间一样,但是较大列会使用较大的内存,mysql通常会分配固定大小的内存块来保存值,这对排序或使用基于内存的零时表尤其不好。只分配正好的空间 name varchar(4) tel varchar(11)。

4.blob和text 

  blob不常用 ,mysql不会按照字符的完整长度排序,只会按照max_sort_length规定的排序前几位,mysql不能索引这些数据类型的完整长度,也不能为排序索引,是不是可以理解为就算排序了也不能索引?

b树索引的局限性:

1.联合索引必须是从做到又连续  index(a,b,c) 等价于 index(a),index(a,b),index(a,b,c) 

2.select * from table where b=1,a Like "b%",c=1 ;  其中c不会用到索引,引擎不会优化范围查询后的列

3.a Like "%b" 是不会用到索引的,最左前缀定理。

hash索引  

建立在hash表上的,用于某一列的精确查询,HashMap也是。

InnoDB有一个特别的功能,自适应哈希索引,当InnoDB注意到一些值被很频繁访问,就会在b-tree顶端为这些值建立hash索引,人工智能,66666

前缀索引和索引的选择性:

  有时候索引很长的字符串会使索引很大很慢,索引字符串的前几位可以节约空间并能提高性能,使索引的空间减小但是会降低选择性,选择性是不重复索引值和表的所有行t的比值,范围是1/t~1之间。高选择性的索引好处:可以在查找匹配时过滤掉多余的行,唯一的索引选择性为1。

select  count(distinck left(city ,3))/count(*) as sel3,

    count(distinck left(city ,4))/count(*) as sel4,

    count(distinck left(city ,5))/count(*) as sel5,

    count(distinck left(city ,6))/count(*) as sel6,

    count(distinck left(city ,7))/count(*) as sel7

from city;

可以看出前7位的选择性最好,选择率提升的幅度减小。

alter table city add key(city(7))

前缀索引的缺点不能使用group by 和order by。

后缀索引有时候也有用,可以用来查询电子邮件之类的。

聚集索引:

1.缺点严重依赖插入顺序,如果没有按照主键插入最好在插入之后使用optimize table重新组织一下表。

2.第二索引可能比预想的大,包含了被应用行的主键列。

3.接上,因为包含了主键的列 查询需要两次。

 

posted @ 2017-04-23 14:06  GTM_AI编程  阅读(415)  评论(0编辑  收藏  举报