记面试中问到的MySQL的SQL调优问题

目录

  • 1、场景还原
  • 2、名词解释
  • 3、实践情况
  • 4、个人观点
  • 5、引申问题

1、场景还原

面试官:小伙子,听说你会SQL调优,那我这里有一条SQL,你来帮我调优一下。SQL如下: SELECT * FROM T LIMIT 899999, 10;

表结构如下:

id int(10) primary key,
其他字段……
我:¿¿¿(缓缓打出反问号),这条SQL要干嘛,随机找10条数据吗?
面试官:哦,不好意思,忘记加上排序了SELECT * FROM T ORDER BY id LIMIT 899999, 10;
我:如果id是连续不中断的话可以这样写。 SQL如下:SELECT * FROM T where id >= 899999 LIMIT 0, 10;
面试官:那假如id不是连续的呢?
我:(略加思考)单从SQL优化层面我优化不了了。
面试官:……那我们进行下一个话题……
我:……
面试官:那最后你有什么问题想问我的吗?
我:刚才那条SQL从SQL层面上该如何优化?
面试官:你可以这样写:SELECT * FROM T t where t.id >= (SELECT f.id FROM T f ORDER BY id DESC LIMIT 899999, 1) LIMIT 0, 10;
我:(假装略加思考)你确定这样写会比图一这条SQL:SELECT * FROM T ORDER BY id LIMIT 899999, 10;更快吗?在图一的SQL里已经是通过主键索引去查询数据了,你图二的SQL并没有改变原有的查找方式。如果你原有SQL是通过其他字段去排序的,用的是非主键索引,例如:SELECT * FROM T ORDER BY createdTime LIMIT 899999, 10;那么你第二条SQL的写法确实会比第一条SQL快得多,因为在MySQL里非主键索引与主键索引在查找上的区别是,非主键索引他存储的是索引列与主键列的值,查找具体的值还需要一次回表过程,而主键索引存储了是整行数据,不需要再次***回表***[^①]查找,减少了一次查找过程。
面试官:……
我:……

2、名词解释

回表

指查找时通过非主键索引(非聚簇索引)去查找对应的记录的主键后,仍需要根据主键进行再一次的查找,这是MySQL的索引结构引起的。在MySQL中,主键索引(聚簇索引)存储的是一整行的数据,而非主键索引(非聚簇索引)存储的是主键列的值。

假如有这样一张表

CREATE TABLE person (
    id int(11) NOT NULL,
    name varchar(32) NOT NULL,
    age int(11) NOT NULL,
    PRIMARY KEY (id),
    KEY idx_person_age (age)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

那这张表的索引具体表现形式如下:

主键索引:

记面试中问到的MySQL的SQL调优问题_第1张图片

非主键索引:

记面试中问到的MySQL的SQL调优问题_第2张图片

所以当我们需要查找age=30的数据时,他的查找过程如下图:记面试中问到的MySQL的SQL调优问题_第3张图片

3、实践情况

如今我有这样一张表:
CREATE TABLE file (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(255) DEFAULT NULL,
  created_time datetime NOT NULL,
  updated_time datetime NOT NULL,
  PRIMARY KEY (id),
  KEY idx_file_created_time (created_time) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=954185 DEFAULT CHARSET=utf8mb4;
表的数据数量为:
先来看看面试官说的情况

记面试中问到的MySQL的SQL调优问题_第4张图片

可以看出,查询时间并没有很大的差距,这是因为这两条SQL都是走的主键索引,方式并没有很大的差别
而我列举的情况,通过时间字段进行排序,让其产生回表操作的过程。

记面试中问到的MySQL的SQL调优问题_第5张图片

可以看出,查询时间出现了很大的差距,这是由于回表操作所造成的。

4、个人观点

这个场景就发生在我上星期的面试中,我不知道这个面试官出这个题时是故意留坑还是什么情况,但是在后面他给出他那答案时,实在是让我惊讶,希望他是一时的错误,若是他对SQL的本身理解就不熟悉,那就……………………

5、引申问题

(1)在file表中,假如我所查询的数据列只有id、created_time与updated_time,那么还可以怎么做?
(2)当真的只能通过id进行排序分页时,我们该怎么做?

你可能感兴趣的:(面试经历,数据库,程序人生,mysql,sql,数据库,SQL调优,性能优化)