一、建表原则
1、定长(time,int,char)字段与变长(varchar,text等)字段分离,不要建在同一张表中。
优点:只包含定长字段的表可以快速定位,例如:假设每行字段占255个字节,要找第100001行,通过计算100001255可快速定位到要找的行。*
2、常用字段和不常用字段分离
3、一对多关系中,若需统计一对应多少行,例如一个产品分类下可能对应100个产品,建议在产品分类表中增加一个冗余字段comodityNum,减少后续计算困难。
二、选列原则
1、字段类型优先级选择:int > data/time > enum/char > varchar > blob/text
int:定长,没有地域之分,没有字符集排序差异
2、字段长度够用就行
三、索引优化
1、b-tree索引(使用二叉树建立索引,快速定位要查找的行,如2的3次方=8,最多查找3下就可以定位到想要的数据,2的32次方约等于40几亿,最多查询32下即可寻找到数据,索引大大加快数据查找的速度)(图一)
2、hash索引哈希
首先简单了解一下Hash算法:(图二)
hash 与B-tree对比,或者说为什么我们一般用B-tree索引:
A:以图一为例:查找大于4的的所有结点
B-tree中,可把4右边的树枝直接砍下来,就能获得大于4的所有节点;
hash由于离散型太强,没办法快速查找大于4的数,需要一个个寻找,5、6、7依次各找一下。
B:例如要在姓名这个字段中查找姓李的所有用户,like “李*”,在B-tree中能稍微发挥作用,hash索引无法发挥作用
C:hash也没有办法排序优化(因为离散型太强)
B-tree虽然好用,但也存在一些误区:
在where条件上的所有字段上都加上索引,所有列都能实现索引效果,
例如:where c_id=3 and price>100,
因为c_id 和price 是独立索引,只能用上一个,就像新华字典,用了拼音索引查字就没办法同时用偏旁部首查字。
那如何才能同时用上2个索引呢?
建立联合索引,以下是建表和索引的SQL,看看哪些情况下这个联合索引才会生效。
使用explain+查询SQL可分析用到了哪些索引,如
EXPLAIN SELECT * FROM aa WHERE userid=‘2222’;
explain具体用法见连接:https://blog.csdn.net/BigGod_lxj/article/details/104942935
四、聚簇索引与非聚簇索引介绍
一、MyISAM
MyISAM下的文件:frm、MYD、MYI分别是myisam引擎表的结构文件,数据文件,索引文件,索引文件与数据文件分离,这就是非聚簇索引。
二、Innodb
innodb的索引文件上,直接存放该行的数据,成为聚簇索引,次索引指向对主键的索引,例如表A中有主索引ID,次索引price,数据存储在主索引ID的文件上,次索引文件上不放具体数据,指向主索引。
相比Myisam的优点:
A:根据主键查询时,不用回行,行数据已经存储在索引文件上
相比Myisam的缺点:
A:当主键数据不规律插入时,如插入1,30,9999,678,333时,会很慢。
我们可以根据不同的引擎建立适合的索引。
五、建立索引一般遵循的原则
1、查询频繁(经常被查询)
2、字段长度小(存储字节太长的字段一般不适合做索引)
3、区分度高(例如产品名称的区分度就比 性别高,性别只有男女之分,产品名称却五花八门)
对于左前缀不易区分的字段该如何处理呢?如
http://www.baidu.com
http://www.taobao.com
可操作的解决办法一:把数据倒序存储再建立索引
4、索引尽量能覆盖常用的查询字段。
六、简单实例介绍(根据实际的业务需求)
根据京东用户的操作习惯及业务规则建立最少量的索引。
假设用户进入首页根据产品类别进行购买产品(若用户在首页直接根据产品名称进行搜索,则可根据产品名称建立索引),具体的索引建立过程,如下图介绍:
七:若一个网站很慢,叫你进行优化,要怎么处理呢?
写脚本收集大约一周内,使用最频繁的那些SQL语句,看看用到哪些表,哪些字段,再根据实际情况建立索引,或者修改索引。