什么是数据库索引?索引有哪几种类型?什么是最左前缀原则?索引算法有哪些?有什么区别?

索引是对数据库表中一列或多列的值进行排序的一种结构。一个非常恰当的比喻就是书的目录页与书的正文内容之间的关系,为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。
主键索引:
数据列不允许重复,不允许为NULL.一个表只能有一个主键。
唯一索引:
数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。
可以通过
ALTER TABLE table_name ADD UNIQUE (column);
创建唯一索引
可以通过
ALTER TABLE table_name ADD UNIQUE (column1,column2);
创建唯一组合索引
普通索引:
基本的索引类型,没有唯一性的限制,允许为NULL值。
可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引
可以通过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);创建组合索引
全文索引:
是目前搜索引擎使用的一种关键技术。
可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引
最左前缀

顾名思义,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
还有一个就是生效原则 比如

index(a,b,c)
where a=3   只使用了a
where a=3 and b=5   使用了a,b
where a=3 and b=5 and c=4   使用了a,b,c
where b=3 or where c=4  没有使用索引
where a=3 and c=4   仅使用了a
where a=3 and b>10 and c=7  使用了a,b
where a=3 and b like 'xx%' and c=7  使用了a,b

索引算法有 BTree Hash
BTree是最常用的mysql数据库索引算法,也是mysql默认的算法。因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量,
例如:

select * from user where name like 'jack%';
如果一通配符开头,或者没有使用常量,则不会使用索引,例如:
select * from user where name like '%jack'; 

Hash
Hash索引只能用于对等比较,例如=,<=>(相当于=)操作符。由于是一次定位数据,不像BTree索引需要从根节点到枝节点,最后才能访问到页节点这样多次IO访问,所以检索效率远高于BTree索引。
BTree索引是最常用的mysql数据库索引算法,也是mysql默认的算法。因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符
例如:

只要它的查询条件是一个不以通配符开头的常量
select * from user where name like 'jack%';
如果一通配符开头,或者没有使用常量,则不会使用索引,例如:
select * from user where name like '%jack';

Hash Hash索引只能用于对等比较,例如=,<=>(相当于=)操作符。由于是一次定位数据,不像BTree索引需要从根节点到枝节点,最后才能访问到页节点这样多次IO访问,所以检索效率远高于BTree索引。
索引设计的原则?
1、适合索引的列是出现在where子句中的列,或者连接子句中指定的列
2、基数较小的类,索引效果较差,没有必要在此列建立索引
3、使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度,这样能够节省大量索引空间
4、不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。
如何定位及优化SQL语句的性能问题?
对于低性能的SQL语句的定位,最重要也是最有效的方法就是使用执行计划。
我们知道,不管是哪种数据库,或者是哪种数据库引擎,在对一条SQL语句进行执行的过程中都会做很多相关的优化,对于查询语句,最重要的优化方式就是使用索引。
而执行计划,就是显示数据库引擎对于SQL语句的执行的详细情况,其中包含了是否使用索引,使用什么索引,使用的索引的相关信息等。

执行计划包含的信息
id
有一组数字组成。表示一个查询中各个子查询的执行顺序;

id相同执行顺序由上至下。
id不同,id值越大优先级越高,越先被执行。
id为null时表示一个结果集,不需要使用它查询,常出现在包含union等查询语句中。

select_type
每个子查询的查询类型,一些常见的查询类型。

table 查询的数据表,当从衍生表中查数据时会显示 x 表示对应的执行计划id partitions 表分区、表创建的时候可以指定通过那个列进行表分区。 举个例子:

create table tmp (id int unsigned not null AUTO_INCREMENT,name varchar(255),PRIMARY KEY (id)
) engine = innodb
partition by key (id) partitions 5;


type(非常重要,可以看到有没有走索引)
访问类型

ALL 扫描全表数据
index 遍历索引
range 索引范围查找
index_subquery 在子查询中使用 ref
unique_subquery 在子查询中使用 eq_ref
ref_or_null 对Null进行索引的优化的 ref
fulltext 使用全文索引
ref 使用非唯一索引查找数据
eq_ref 在join查询中使用PRIMARY KEYorUNIQUE NOT NULL索引关联。

possible_keys
可能使用的索引,注意不一定会使用。查询涉及到的字段上若存在索引,则该索引将被列出来。当该列为 NULL时就要考虑当前的SQL是否需要优化了。
key
显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL。
TIPS:查询中若使用了覆盖索引(覆盖索引:索引的数据覆盖了需要查询的所有数据),则该索引仅出现在key列表中
key_length
索引长度
ref
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
rows
返回估算的结果集数目,并不是一个准确的值。
extra
的信息非常丰富,常见的有:

Using index 使用覆盖索引
Using where 使用了用where子句来过滤结果集
Using filesort 使用文件排序,使用非索引列进行排序时出现,非常消耗性能,尽量优化。
Using temporary 使用了临时表
sql优化的目标可以参考阿里开发手册

某个表有近千万数据,CRUD比较慢,如何优化?分库分表了是怎么做的?分表分库了有什么问题?有用到中间件么?他们的原理知道么?

数据千万级别之多,占用的存储空间也比较大,可想而知它不会存储在一块连续的物理空间上,而是链式存储在多个碎片的物理空间上。可能对于长字符串的比较,就用更多的时间查找与比较,这就导致用更多的时间。

可以做表拆分,减少单表字段数量,优化表结构。
在保证主键有效的情况下,检查主键索引的字段顺序,使得查询语句中条件的字段顺序和主键索引的字段顺序保持一致。

主要两种拆分 垂直拆分,水平拆分。

垂直分表
也就是“大表拆小表”,基于列字段进行的。一般是表中的字段较多,将不常用的, 数据较大,长度较长(比如text类型字段)的拆分到“扩展表“。 一般是针对那种几百列的大表,也避免查询时,数据量太大造成的“跨页”问题。
垂直分库针对的是一个系统中的不同业务进行拆分,比如用户User一个库,商品Producet一个库,订单Order一个库。 切分后,要放在多个服务器上,而不是一个服务器上。为什么? 我们想象一下,一个购物网站对外提供服务,会有用户,商品,订单等的CRUD。没拆分之前, 全部都是落到单一的库上的,这会让数据库的单库处理能力成为瓶颈。按垂直分库后,如果还是放在一个数据库服务器上, 随着用户量增大,这会让单个数据库的处理能力成为瓶颈,还有单个服务器的磁盘空间,内存,tps等非常吃紧。 所以我们要拆分到多个服务器上,这样上面的问题都解决了,以后也不会面对单机资源问题。
数据库业务层面的拆分,和服务的“治理”,“降级”机制类似,也能对不同业务的数据分别的进行管理,维护,监控,扩展等。 数据库往往最容易成为应用系统的瓶颈,而数据库本身属于“有状态”的,相对于Web和应用服务器来讲,是比较难实现“横向扩展”的。 数据库的连接资源比较宝贵且单机处理能力也有限,在高并发场景下,垂直分库一定程度上能够突破IO、连接数及单机硬件资源的瓶颈。
水平分表
针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。 但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。不建议采用。
水平分库分表
将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。
水平分库分表切分规则

RANGE从
0到10000一个表,10001到20000一个表;
HASH取模
一个商场系统,一般都是将用户,订单作为主表,然后将和它们相关的作为附表,这样不会造成跨库事务之类的问题。 取用户id,然后hash取模,分配到不同的数据库上。
地理区域
比如按照华东,华南,华北这样来区分业务,七牛云应该就是如此。
时间
按照时间切分,就是将6个月前,甚至一年前的数据切出去放到另外的一张表,因为随着时间流逝,这些表的数据 被查询的概率变小,所以没必要和“热数据”放在一起,这个也是“冷热数据分离”。

分库分表后面临的问题

事务支持
分库分表后,就成了分布式事务了。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价; 如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。

跨库join
只要是进行切分,跨节点Join的问题是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。
分库分表方案产品

跨节点的count,order by,group by以及聚合函数问题
这些是一类问题,因为它们都需要基于全部数据集合进行计算。多数的代理都不会自动处理合并工作。解决方案:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并。和join不同的是每个结点的查询可以并行执行,因此很多时候它的速度要比单一大表快很多。但如果结果集很大,对应用程序内存的消耗是一个问题。

数据迁移,容量规划,扩容等问题
来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制。总得来说,这些方案都不是十分的理想,多多少少都存在一些缺点,这也从一个侧面反映出了Sharding扩容的难度。

ID问题

一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由.
一些常见的主键生成策略

UUID
使用UUID作主键是最简单的方案,但是缺点也是非常明显的。由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建立索引和基于索引进行查询时都存在性能问题。
Twitter的分布式自增ID算法Snowflake
在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位 机器ID 10位 毫秒内序列12位。

跨分片的排序分页
般来讲,分页时需要按照指定字段进行排序。当排序字段就是分片字段的时候,我们通过分片规则可以比较容易定位到指定的分片,而当排序字段非分片字段的时候,情况就会变得比较复杂了。为了最终结果的准确性,我们需要在不同的分片节点中将数据进行排序并返回,并将不同分片返回的结果集进行汇总和再次排序,最后再返回给用户。如下图所示:

中间件推荐

mysql中in 和exists 区别

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询。一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的。这个是要区分环境的。

如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

感兴趣的可以自己来我的Java架构群,可以获取免费的学习资料,群号:855801563 对Java技术,架构技术感兴趣的同学,欢迎加群,一起学习,相互讨论。

转载于:https://blog.51cto.com/13981400/2338827

互联网公司面试必问的mysql题目相关推荐

  1. 互联网公司面试必问的mysql题目(下)

    这是mysql系列的下篇,上篇文章地址我附在文末. 什么是数据库索引?索引有哪几种类型?什么是最左前缀原则?索引算法有哪些?有什么区别? 索引是对数据库表中一列或多列的值进行排序的一种结构.一个非常恰 ...

  2. 互联网公司面试必问的mysql题目(上)

    又到了招聘的旺季,被要求准备些社招.校招的题库. 介绍:MySQL是一个关系型数据库管理系统,目前属于 Oracle 旗下产品.虽然单机性能比不上oracle,但免费开源,单机成本低且借助于分布式集群 ...

  3. 互联网公司面试必问的Redis题目

    https://juejin.im/post/5b99d4bce51d450e7a24b66e#heading-0 Redis是一个非常火的非关系型数据库,火到什么程度呢?只要是一个互联网公司都会使用 ...

  4. Java面试必问!mysql分页查询

    前言 高并发,几乎是每个程序员都想拥有的经验.原因很简单:随着流量变大,会遇到各种各样的技术问题,比如接口响应超时.CPU load升高.GC频繁.死锁.大数据量存储等等,这些问题能推动我们在技术深度 ...

  5. 运维面试必问的MySQL高频面试题(2021年最新版)

    前言 网上的运维面试题文章有非常多,在我的博客中也有一些是这些年运维人员面试的面试题,之前一些经典的面试题我已经整理到专栏<运维面试宝典>里,这个专栏里的面试技巧可以说永远不会过时,而且我 ...

  6. Java岗面试必问!mysql视频教程百度云

    阻塞IO 我们知道在调用某个函数的时候无非就是两种情况,要么马上返回,然后根据返回值进行接下来的业务处理.当在使用阻塞IO的时候,应用程序会被无情的挂起,等待内核完成操作,因为此时的内核可能将CPU时 ...

  7. Java面试必问的MySQL锁与事务隔离级别

    前言 众所周知,事务和锁是mysql中非常重要功能,同时也是面试的重点和难点.本文会详细介绍事务和锁的相关概念及其实现原理,相信大家看完之后,一定会对事务和锁有更加深入的理解. 什么是事务 在维基百科 ...

  8. 字节Java面试必问:mysql索引类型属于

    1 进程 进程与程序 操作系统之中最为通用的概念就是「进程」.与此相关的面试题以及各种技术优化策略也层出不穷,足以够证明它对于理解操作系统中举足轻重的地位.事实上,通过「进程」,程序员可以更为直观的理 ...

  9. mysql什么隔离级别最好_面试必问的 Mysql 四种隔离级别,看完吊打面试官

    什么是事务 事务是应用程序中一系列严密的操做,全部操做必须成功完成,不然在每一个操做中所做的全部更改都会被撤消.也就是事务具备原子性,一个事务中的一系列的操做要么所有成功,要么一个都不作.sql 事务 ...

最新文章

  1. 【数据挖掘】理解数据挖掘
  2. 下一个嵌入式大神,难道不是你吗?
  3. oracle 不认exp指令,更改oracle字符集导致exp命令出错(解决方法)
  4. android 获取录音时长_录音转文字,支持安卓和IOS和PC
  5. java课程设计(总结)
  6. 《成功者的窘境》克里斯滕森 epub+mobi+azw3
  7. word另存为pdf后,pdf文件中有空白页
  8. VS code react插件快捷键
  9. visio增加连接点
  10. 使用ffmpeg将视频转成HLS(m3u8)格式
  11. 递推最小二乘法RLS的轮胎侧偏刚度估计(原书缺失代码已补全)
  12. android studio购物车开发,2018-03-21 - 购物车项目说明 - 界面功能实现相关
  13. 梯度提升树(GBDT)
  14. 手机计算机怎么缩小桌面图标,如何将电脑桌面快捷图标放大或缩小
  15. SQL图文讲解操作12-多表查询
  16. 视频话题识别与跟踪 - demo 【问题总结1.0-爬虫方面】
  17. RNN、LSTM、GRU实战——imdb情感分析
  18. android 6.0 EC20驱动移植
  19. TSINGSEE青犀视频监控技术在城市轨道交通中的应用
  20. 爬取BOSS直聘信息并进行清理和可视化分析(python小白)

热门文章

  1. 函数中结构体指针作为形参修改指针地址
  2. 基础008_定浮点转化[floating point IP]
  3. spring源码核心:DefaultListableBeanFactory
  4. python中高阶函数map怎么用_python六十课——高阶函数之map
  5. android仿优酷菜单,Android编程实现仿优酷旋转菜单效果(附demo源码)
  6. configure 查找依赖库_由浅入深:Python 中如何实现自动导入缺失的库?
  7. html文件图标变成白色,win10系统html文件图标变成空白的操作办法
  8. 购物车及商品php代码_简单的php购物车代码
  9. 普适计算机的应用领域有哪些,2017年度计算机科学各领域热点词汇
  10. 图上上传页面设计_无线端页面设计“三大雷区”