mysql优化-索引篇(草稿)

说到索引优化,你是否只能说出:在where字段加索引,唯一索引,联合索引,普通索引等等。

可是,你知道B-tree,T-tree或者hash索引么?

 

hash索引在memory使用。

 

最好的设计是索引覆盖!  需要精心设计,不是一定可以达成的

hash索引劣势

1  随机读取    对机械硬盘来说,顺序读取是随机读取速度的几十倍!

2 不支持左前缀    存储helloworld --索引字段  like  "hello%"--   hash(hello) 和 hash(helloworld)无任何联系   

3 排序支持不好  因为1,不连续,根据hash存放而不是排序顺序!

4 范围支持不好  因为1,不连续,根据hash存放而不是范围!

5  必须回行!因为很难逆运算

 

hash索引的劣势就是B-tree的优势!

 

B-tree常见误区

误区1:

select * from  xxx where x1=x and x2=y...

x1和x2有独立的索引,只用其一!而不是全部使用!!

可以建立多列索引

 

误区2:

多列索引,where每一个字段用索引?

要满足左前缀!

多列索引具体使用规则例

**********************************

1、index(a,b,c)

2、where a = 1  yes

3、where b=2  ,where c=3  no 

4、where a=1 and b=2 yes

5、where a=1 and b=2 and c=3 yes

6、where a=1 and c=2  a可以

7、where a=1 and b>5 and c=2   a,b可以,c不可以

8、where a=1 and b like "xxx%" and c =2  a,b可以,c不可以

7和8是因为b发生了范围,之后就不可以使用

************************************

多列索引使用规则:

1 要满足左前缀!

2 范围匹配(like  or  >)之后不可用!

帮助理解的案例:桥接板!

 

mysiam与innodb存储引擎的不同:

mysiam索引的指针指向物理数据地址  

innodb索引的指针指向主键索引  因为物理存储上物理数据挂在主键上

 

问题  innodb如果没设置主键呢?

1 如果没人为设置主键,则系统选取unique,如果没有unique,则系统声称一个内部rowid作为主键。

这种类型的索引就是--聚簇索引!

 

=========问题分割线===============

disable keys 作用?  

官方描述:让MySQL停止更新 MyISAM表中的非唯一索引

1  更新----并不是禁用  而是停止更新   (试验,待做!)

2  myisam表

3  非唯一

==============================

高性能索引:

一 长度的选择

考虑因素: 区分度,长度!

测试:select count(distinct left(字段,长度))/count(*) from xxx;

不停变换长度来区分!

结论:区分度>0.1就合格!

 

技巧篇:

对于左前缀不易区分的字符串,可以:

1,倒转字符串来存!  左截取

2,hash(url),可以用crc32等   针对hash_url 来降低长度

 

 

二  多列索引顺序选择:

查询频率(更优先考虑)区分度

区分度测试: select count(distinct 索引字段)/count(*) from xxx;

结论:区分度>0.1就合格!

 

三 聚簇索引

B-tree树的结点上就存储数据,而不是指向数据的指针(myisam)。

innodb就用的聚簇索引。

 

页分裂

innodb的概念,以及试验证明。  

结论:聚簇索引最好顺序存取。

虽然是随机写入,但select 的时候是按主键顺序的!!!

 

四 极限优化法--索引覆盖

作用:防止回行!

问:如何添加索引?

答:嗯。。在where字段加索引。。。这远远不够!!!!!

在常搜索的字段上也要加索引,和where字段一起构成多列索引!可以防止回行!理解原理就不难了啊。。。

 

innodb啊!陷阱啊!!!!独立索引也可能会引用到主键啊啊!!!

 

五:延迟关联

select * from xxx where name like "%x%";

select a.* from xxx t1 inner join (select id from xxx where name like "%x%") t2 on t1.id =t2.id;

第二种做法使用了延迟关联,针对innodb!语句复杂,但速度却稍占优势

总结:

内层查询只沿着索引层找出主键id,一次性读值。

语句1是每找到一个id,就读值。

这只是一个在innodb中的小技巧!  适用于内存查找比较少!

疑问: 是只再innodb上还是myisan也会去物理层读取?(试验,待做)

 

mysql引擎参数调优:缓冲神马的有时间再写,这么多参数记不住啊记不住!

nnodb_flush_method =  O_SYNC/O_DSYNC(unix)  如果是linux可以直接设置为O_DIRECT   

innodb和系统打交道的一个参数。  

 

 

 

 

 

 

 

 

 

posted @ 2013-09-14 20:36  优雅的c  阅读(333)  评论(0编辑  收藏  举报