Java常见面试题之MySQL

索引有哪些

        数据库常见的索引类型有:主键索引 唯一索引 普通索引 全文索引 组合索引

        普通索引,最常见的索引

alter table table_name add index index_name (coumn_name);

        唯一索引,索引列的值是唯一的,可以为null

alter table table_name add unique (colunm_name);

        主键索引,设置主键的时候自动创建的索引,属于特殊的唯一索引.特殊在于不能为null

alter table table_name add primary key (column_name);

        组合索引,给多个字段添加索引叫做组合索引

alter table table_name add index index_name (colunm1,colunm2...);

        全文索引,只有char varchar text类型可以添加全文索引,全文索引用于搜锁一篇很长的文章时,效果很好,用在比较短的文本,可以使用普通的index;

alter table table_name add fulltext index_name (colunm_name);

        使用全文索引

select * from student where match(name) against('梁')

项目中哪些操作导致索引失效

  1. 类型不一致的索引失效,在设置表字段时一定要保证数据类型的一致性.在作为条件查询时需要先进行类型转换,此时索引就失效了,例如  age='18'    age=18
  2. 函数导致的索引失效
  3. 模糊查询导致的索引失效,如果模糊查询的条件是以通配符开头的,它不会走索引.
  4. 使用!= 或者<>导致索引失效,

索引有什么优缺点

        优点:

  • 创建索引可以大幅提高系统性能,帮助用户提高查询效率
  • 通过索引的唯一性,可以保证数据库中每一行数据的唯一性.
  • 可以加速表与表之间的链接
  • 降低查询中分组和排序的时间,

        缺点:

  • 索引的存储需要占用磁盘空间
  • 当数据量非常大时,索引的创建和维护所耗费的时间也是相当巨大的
  • 每当执行cru操作时,索引也需要动态维护,降低了数据的维护速度.

        总结:

        一般来说,创建索引的情况需要排除一下情况:

  • 在查询中很少使用的列不应该创建索引.因为这些列很少使用到,因此有索引或者无索引都不会提高查询效率.相反,增加了索引之后,降低了系统的维护速度和增大了空间需求.
  • 数据值很少的表格也不应该创建索引,因为当数据太少的时候,全盘搜索可能都比索引查找还快,就没有必要创建索引了,反而还会降低磁盘空间和性能
  • 定义为text image 和bit数据类型的列不应该创建索引,因为这种列的数据要么是非常大,要么非常少
  • 当修改性能远大于检索性能时不应该创建索引.因为修改性能和检索性能是相互矛盾的,两者只会一增一减.

最左匹配原则

        最左匹配原则,在使用联合索引之后,如果查询条件中包含联合索引中最左边的列,就会按照索引查询,再去匹配第二列,一直向右匹配,直到遇到范围查询的条件就会停止.如(< > between 等等)

        假如我们现在给 a b c 建立联合索引,

alter table t1 add index un (a,b,c);

        在给abc建立联合索引,会先给a列建立索引,之后在a的基础上建立b的索引,在次基础上建立c的索引.如果同时存在abc3个条件,比如 a=1 b=3 c=2,会先按照建立索引时的顺序(a,b,c)的最左边的索引,也就是a,进行查询,之后再使用第二列,也就是b,进行查询.一直到最右边的列为止.可以看一下下面的图(原理是b+树,但是这里考虑到新手友好,就没有用b+树的图,而是使用了较为日常的一种方式,excel的排序逻辑):

Java常见面试题之MySQL_第1张图片

         其实上面这个图的逻辑是很直观的

        只要我们建立了联合索引,在查询条件中包含了联合索引中从最左侧索引开始的一部分索引,这部分索引就会生效.还是举个例子,比如我们现在的查询条件是a=1  b=2,c不在条件之内,按照索引建立的顺序,我们还是先根据a,筛选出一部分,再根据b查找出一部分.根据这个条件去筛选上面图中的数据,还剩3条,由于我们没有指定c的条件,所以会直接返回这3条数据

        如果查询条件中包含了部分索引,但是不包含最左侧的索引,那整个联合索引都是不生效的.例如,我们现在的条件是b=2,c=2,这里我们没有指定a的值,所以无法确定我们b=2的查询范围.要知道,我们的索引是先建立的a,会先根据a的值进行排序,之后在a相同的数据中再用b排序,所以就可能就会出现,a=1的数据中存在b=2的数据,但是a=2的数据中也存在b=2的数据,但是这些数据的排列并没有规则,所以只能进行全表扫描,这样就相当于索引失效,同理,如果条件是a=1,c=3.那么索引a会生效,c是不生效的,原理一致.

        一直向右匹配,直到遇到范围查询的条件就会停止.如(< > between 等等),了解了上一条机制,不包含最左侧的索引就会失效是因为我们筛选的数据在某种程度上是无序的,所以我们现在的查询条件是这样的,a=1,b>1,c=3.首先,a是生效的,这毫无疑问,b也生效,因为我们在经过a的筛选之后,b的排列也变的有序,但是c呢,我们根据b>1查出的会有多组数据.在这些数据里面,b=2的数据中.存在c=3,b=3的数据中也存在c=3,所以跟上面的机制一样,对于c来说又变成了无序,所以遇到范围查询的条件就会停止,a=1,b>1,c=3中a b生效,c无效

        这就是最左匹配原则.

存储引擎InnoDB和MyISAM的区别

  • 锁机制不同,InnoDB支持行级锁和表级锁,默认是行级锁,MyISAM支持表级锁.MyISAM的表级锁是类似于读写锁的,在读的时候是共享锁,写的时候是独占锁.在读操作的时候不会影响读数据的效率,但是写的时候会直接锁住整张表,在写操作并发量较大的时候,不如InnoDB
  • 事务不同,InnoDB支持事务,而且在没有手动使用事务的情况下,它默认将每一条sql语句都看做一个事务.MyISAM不支持事务
  • InnoDB支持外键,但是MyISAM不支持外键.
  • MyISAM支持表不设置主键,但是InnoDB必须要设置主键,如果没有设置主键,会自动生成一个6字节的隐藏列作为主键
  • MyISAM在数据库崩溃之后不支持数据恢复,InnoDB支持,主要依赖于redo log , undo log,bin log

你可能感兴趣的:(mysql,数据库)