一:索引有哪些模型各有什么优缺点?
索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。
常见的索引模型有;哈希,数组,树。
哈希表:哈希表只适合于等值查询,范围查询走全表扫描。
数组:等值和范围查询都很好,但是插入和删除的代价太高。所以有序数组只适合静态存储引擎。
数:等值和范围均可以。
二:innodb的索引特点,mysiam的索引特点。innodb要用什么做主键,为什么,有没有什么特里。
innodb是索引组织表。主键索引的叶子节点保存的是整行数据,也叫聚簇索引。普通索引的叶子节点是主键id。
mysiam索引。主键索引和普通索引的叶子节点均是行数据的地址,不同的是,一个是唯一索引,一个不是唯一索引。
innodb用自增id做主键,一是主键会自增,插入操作,直接追加,不会有页分裂。二是,普通索引的叶子节点是主键,主键值较小,普通索引占用空间小。但是业务表里面有一个字段唯一,且是唯一的索引时,要用业务字段做主键,对应于key=>value场景。
三:怎样进行索引优化?
1.使用覆盖索引,减少回表。
2.因为只要满足最左前缀,就可以利用索引来加速检索。这个最左前缀可以是联合索引的最左n个字段,也可以是字符串索引最左M个字符。所以,可以通过调整联合索引的顺序,少维护一个索引。
3.mysql5.6引入的索引下推优化,可以在索引遍历过程中,随索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表的次数。
4.如果业务数据有唯一值,尽量用普通索引,而不是唯一索引。如果是更新多,读少的业务,直接用普通索引。如果是更新少,读多的业务,如果用普通索引,把change buffer关掉就可以了。用唯一索引也可以。因为普通索引,更新操作中用到的change buffer ,能显著提高更新性能,所以在写多读少的应用,如日志,普通索引+change buffer能显著提高性能。
5.给字符串加索引,字符串太长,比较占空间。
1)使用前缀索引,比较省空间,但是会增加扫描次数,并且不能使用覆盖索引。
2)倒序存储,使用前缀索引,解决区分度不够。但是只能用于等值查询。
3)创建hash字段索引,也只能等值查询。
6.order by语句的,尽量在where条件和order by 字段建联合索引,这样order by 就不用Mysql系统排序了。
7.不要在查找字段上加上函数,加函数以后,走不了树搜索。join操作连接字段,字段类型需要一致,where条件,查找值也需要与字段类型一致,否则会加隐式转换函数,同样走不了数搜索。
8.如果小表驱动大表,并且可以用上被驱动表上的索引,是可以用join的【NLJ算法】。如果用不上索引,使用小表驱动大表,使用的是【BNL算法】】,如果表数据大,占用资源较多,不建议使用。使用BKA算法对NLJ算法优化。给join字段加索引,让BNL算法转化成BKA算法。
9,group by语句的优化,group by语句没有排序要求,语句后面加order by null;尽量让group by 过程用索引,确认方法是explain 结果里没有Using temporary和Using filesort;如果group by 需要统计的数据量不大,尽量只使用内存临时表,也可以通过适当调大tmp_table_size参数,来避免用到磁盘临时表。如果数据量实在太大,使用SQL_BIG_RESULT这个提示,来告诉优化器直接使用排序算法得到group by 的结果。
四:为什么数据表删掉一半,表文件大小不变?
因为只是将数据标为可复用。[innodb_file_per_table=on 表数据存储在.idb为后缀的文件】。
所以表经常增删改,会出现很多空洞,所以需要重建表。去掉表中存在的空洞。使用 alter table A engine=InnoDB来重建表,5.5版本之前用的是线下的 ,5.6版本之后引入online DDL。
五:mysiam和innodb引擎的count(*)哪个快,为什么?
mysiam快,因为mysiam中count(*)存在 磁盘中,而innodb一行一行读数据。因为innodb有并发控制的原因,所以同一时刻,不同线程中count(*)可能不同。但是数据量特别大的时候,count(*)返回比较慢,怎样优化。最好将count(*)的值缓存,存在redis不合适,因为不同的存储构成的系统,不支持分布式事务,无法拿到精确一致的视图。把计数放到mysql中,就解决了一致性视图的问题。
六;order by 语句如何优化?
order by 排序在sort buffer中,并且如果排序的数据量超过sort_buffer_size。还要用到磁盘临时文件辅助排序,非常耗内存。如果待排序的字段已经是排序好的,比如索引,就用不到sort buffer了。所以优化order by ,要尽量用索引。
七:查询一条语句,长时间不返回。
1.扫描了太多行。
2.等MDL锁。等行锁。等flush
八:group by 语句如何优化?
1.如果对group by语句的结果没有排序要求,要在语句后面加order by null。
2.尽量让group by 过程用上表的索引,确认方法是explain结果里没有Using temporary和Using filesort。
3.如果group by 需要统计的数据量不大,尽量只使用内存临时表;也可以通过适当调大tmp_table_size参数,来避免用到磁盘临时表。
4.如果数据量实在太大,使用SQL_BIG_RESULT这个提示,来告优化器直接使用排序算法得到group by 的结果
八:什么是内存表,有什么用?
内存表,指的是使用memory引擎的表,建表语法是create table ...engine =memory.这种表数据保存在内存中。
系统重启的时候会被清空,但是表结构还在。
九:临时表,内部临时表,memory引擎表特点,各有什么用?在什么场合用,有什么优缺点?
临时表只能被创建它的session访问,对其他线程不可见,与普通表重名时,增删改查访问的是临时表,session结束,自动被回收。
















