【PHP面试题】简单描述MySQL中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响?

文章目录

    • 一、考点
      • 1、MySQL索引的基础和类型
        • 1)索引的基础
        • 2)索引对性能的影响
        • 3)索引的使用场景
        • 4)索引的类型
          • 常考题:唯一索引 与主键索引 当前区别是什么?
      • 2、延伸
        • 1)MySQL索引的创建原则
        • 2)MySQL索引的注意事项
    • 二、解题方法
    • 三、真题
        • 创建 MySQL复合索引(组合索引) 应该注意哪些事项?

一、考点

1、MySQL索引的基础和类型

1)索引的基础

  • 索引类似于书籍的目录,要想找到一本书的某个特定主题,需要先查找书的目录,定位对于的页码。
  • 存储引擎使用类似的方式进行数据查询,先去索引当中找到对应的值,然后根据匹配的索引找到对应的数据行。

2)索引对性能的影响

  • 大大减少服务器需要扫描的数据量(如:数据表中有1000条数据,我们只需要根据条件查询其中的一条,正针对该列创建一个索引,只需要扫描这一条即可;如果不创建索引,我们得扫描1000条);
  • 帮助服务器避免排序和临时表的生成;
  • 将随机 I/O 变成 顺序 I/O;
  • 大大提高查询速度;
  • 降低写(增、删、改)的速度(由于对数据表进行写操作的时候,会额外的操作的操作一遍索引)、占用磁盘(本身来说,索引也是一种数据)。

3)索引的使用场景

  • 对于非常小的表,大部分情况下全表扫描效率更高(不需要创建索引);
  • 特大型的表,建立和使用索引的代价将随之增长,可以使用分区技术来解决

4)索引的类型

索引有很多种类型,都是实现在存储引擎层的。

  • 普通索引最基本的索引,没有任何约束限制。
  • 唯一索引:与普通索引类似,但是 具有唯一性约束
  • 主键索引:特殊的唯一索引,不允许有空值。
  • 组合索引:将多个列组合在一起创建,可以覆盖多个列。
  • 外键索引只有 InnoDB类型的表才可以使用外键索引,保证数据的一致性、完整性和实现级联操作。【基本上不使用】
  • 全文索引MySQL自带的全文索引只能用于 MyISAM,并且只能对英文进行全文检索。【基本上不使用】
常考题:唯一索引 与主键索引 当前区别是什么?
  • 一个表只能有一个主键索引,可以有多个唯一索引;
  • 主键索引一定是唯一索引, 唯一索引不是主键索引;
  • 主键可以与外键 构成 参照完整性约束, 防止数据不一致。

2、延伸

1)MySQL索引的创建原则

① 最适合索引的列是出现在 WHERE子句中的列,或连接子句中的列,而不是出现在 SELECT关键字后的列(where/on 后面的列);

② 索引列的基数越大,索引的效果越好;

③ 对字符串进行索引,应该制定一个前缀长度,可以节省大量的索引空间;

④ 根据情况创建复合索引,复合索引可以提高查询效率;

⑤ 避免创建过多索引,索引会额外占用磁盘空间,降低写操作效率;

⑥ 主键尽可能选择较短的数据类型(如:int/bigint),可以有效减少索引的磁盘占用,提高查询效率。


2)MySQL索引的注意事项

① 复合索引遵循前缀原则;

// 创建一个索引
KEY(a, b, c); 

// 以下3种情况该索引生效:
WHERE a=1 and b=2 and c=3;
WHERE a=1 and b=2;
WHERE a=1

// 以下2情况该索引不生效:
WHERE b=2 and c=3; // 因为跳过了a
WHERE a=1 and c=3; // 因为跳过了b

常考题:

  • 题目:我创建了一个 WHERE a=1 and b=2 或者 WHERE a=1这样的查询,我需要创建一个什么样的索引比较合适?
  • 答案KEY(a, b)

注:KEY(a, b,c) 表示 创建了一个索引,同时作用于a,b,c,目的是为了缩短查询范围(如:创建一个组合索引,章节段,查询第几章中的第几节的第几段,这样缩短了查询的范围)。

② like 查询,% 不能不前,可以使用全文索引;

where name like "%wang%"; // 不要使用该方法

③ column is null 可以使用索引;

④ 如果MySQL估计使用索引比全表扫描更慢,会放弃使用索引;

假设表中有100条数据,在写条件的时候这样写

where id > 1 and id < 100 

即使对 ID设置了索引,在搜索的时候,搜索的是 2~99 之间的数据。

搜索过程:首先找 2 这条数据,去索引中看看它在什么位置,找到索引后,再去定位数据行;然后再去看 3, 再去看索引,再去找数据行,;再去看 4,再去看索引,再去找数据行,… ,一直到 99 都要这样去操作。

所以在这里面本身来说,我们这样来查询,首先我们会多一个查询索引的步骤,所以MySQL认为,本身就100条数据,要查询其中的98条数据,而这98条数据都需要去看索引,所以就很慢,直接把这100条数据都扫描一遍,然后返回其中的98条 不就可以了么,这样效率会更高,它会自动去放弃,不需要我们手动放弃,这是我们优化器做得事。


⑤ 如果 or 前的条件中的列有索引,后面的没有,索引都不会被用到;

where a or b; // 如果a中有索引,b中没有索引,该索引就会失效

⑥ 列类型是字符串类型,查询时一定要给值加引号,否则索引失效。

// 在创建的时候设置了 name varchar(16)
// 搜索的时候,name为100
where name = 100; // 写成这样的形式,可以搜索到,但是没有用到索引【因为本身是字符串类型,而写成了整型】
where name = "100"; // 此时才用到了索引【一定要给值加引号】

二、解题方法

在一些 MySQL索引 基础考题中,我们可以轻松的通过索引基础和类型来解决此类问题,对于一些索引创建注意事项方面的考点,我们可以通过索引创建原则和注意事项来解决。


三、真题

创建 MySQL复合索引(组合索引) 应该注意哪些事项?

  • 遵循前缀原则;
  • 看查询条件(如果查询条件中是 WHERE a=1 AND b=2 我们可以创建一个 KEY(a,b) 这样的复合索引 ,如果搜索 WHERE a=1 时,该索引也可以被使用到)。

你可能感兴趣的:(PHP面试题,MySQL数据库)