索引就是目录检索系统
IOT : index cluster table
表要聚集索引排序后存储
sql语句中带where条件的都会用到索引
idx_abc(a,b,c)—–》(a), (a,b), (a,b,c)
select * from tb where a=xxx; 可以用到索引
select * from tb where b=xxx; 不能用到索引
加速join操作
where a.c_id = b.d_id 要求2个数据类型是一样的
如果不一样也用不到索引比如c_id mediumint,d_id int 2个去join不能进行转换成为临时表
char和varchar 大小一样的情况下可以用到索引 但是只要size定义不一样则不能用到索引
join的场景要求两个类型一样的同时要求size一样才能用到索引
排序可以用到索引
idx_abc(a,b,c)
select a,b,c from tb where a=xxx;
索引包含(Innodb的B+tree,索引内包含数据)
一个表有多列索引怎么选择
select * from tb where c1=xxxx and c2=xxx;
c1 varchar(10)
c2 int(10)
idx_c1(c1)
idx_c2(c2)
查询优化里有一个原则:基于成本优化
统计视图
假设成查询成本是1
c1 string 0.9
c2 int 0.6
mysql认为这个计划都符合要求,就会从上到下取第一个,而我们这里c1比c2靠前所以优先用c1
这就是mysql的 成本优化器
5.7这块可能有变化
trace
《sql server 查询》
基于成本优化内容
R-Tree只在MyISAM里面的地理数据里支持
主建和唯一索引有什么区别吗
主键不允许null,唯一索引允许null
普通索引对null没有要求
使用上会有区别
where col1 =xxx ;
普通索引不能保证数据不重复还会往下面继续查
所以普通索引会比主键和唯一索引多一点io开销
核心类和高并发尽可能用主键或者唯一索引
(tokudb可以有多个主键多个class index)
Innodb只允许有一个主建
数据是以主键为顺序排序存储的
Innodb表以主建排序存储,如果没有主建了怎么办?
如果没有主建,会选择第一个(创建的顺序)唯一索引,升级为主建
如果这个表连唯一索引也没有怎么办?
自动创建一个6个字节长度的主键
6个字节是很长的成本比较高
idx_
udx_
fdx_
前缀索引貌似是mysql的一个特色
email(64) 用20位就已经可以区别出来了就可以创建
create index idx_email on tb(email(20));
让索引使用最少的空间来减少io
联合索引
(c3,c4)
update tb set c6=xxx where c3=xxx and c4=xxx;
如果创建索引了 就不要再这个列上经常更新
update set email
改索引后需要先改字段然后进行索引排序然后再把数据弄过去,可能涉及到拆页分页
所以要避免更新索引列
全文索引
目前(5.6)不支持中文
5.7后貌似支持中文了
http://www.actionsky.com/docs/archives/163
CJK亚洲文字
create fulltext index idx_c5 on yw(c5);
MySQL 5.6 innodb增加了全文搜索
唯一索引(=)效过最好 ,但是也支持区间(>,between, in)
主键定义删除创建智能用lalter table一般都是在表创建的时候去定义,这个动作很大需要copy表空间,生产环境中基本不去动主键这个事情。
isopen
type
flag
这些列不太适合做索引,基数太少了
比如说type就3个值那也就是30%的比例
mysql扫描不低于30%(打比方的值)都不会走索引
这个索引是无效的
如果标志达到4个或者5个以上索引可能还是可以用到的
选择基数比较大的列做索引,或者重复比较少的。
我们目前的status_id呀,type_id呀,action_id呀之类的这些标志我得找个时间去测试一下效果如何
只有基于唯一索引或主键上等于类的操作才能做到行级锁,这部分非常复杂
gap
next key
idx_ab(a,b)
idx_a(a)
后面会有工具来帮助排查
《基于Innodb最佳实践》
无序主键 rand出来
写入速度很慢 1s只能一两百
顺序索引/s能上万
索引无序写入会造成写入速度降低
update 尽可能不要update索引列
5.7对这块update做了一些合并的维护
字符型的索引,是怎么查找的?
字符串比较btree的字符串比较定位到值在哪