关于面试时面试官提出的一些疑问,求解答

2021-08-03 22:04:47 +08:00
 MrGoooo
问题 1:mysql 给表中的 a,b,c 三个列建立联合索引,select * from t where a=1 and b > 2 order by c,面试官问会不会走这个联合索引,我说:会,因为满足了最左前缀匹配。面试说让我下去好好了解了解。

问题 2:面试官问 redis 缓存和数据库一致性问题,我说:增删改的时候先删 redis 缓存再操作数据库。面试官问如果 redis 删除失败了怎么办?我说:redis 操作失败了就抛出异常,不会再对数据库操作。面试官问:如果需要 redis 操作失败的情况下也需要对数据库增删改成功,并且避免读出脏数据,改怎么做?我没想出来。
6558 次点击
所在节点    程序员
48 条回复
CEBBCAT
2021-08-03 22:31:50 +08:00
我也不懂,第一个我没读过引擎源码,不好多说

但第二个这题目的背景我想可以转换为 Redis 不可达,在这种情况下还不想读到脏数据,你鲨了我吧
linyuyizhizou
2021-08-03 23:10:01 +08:00
第一题我也好奇。有大佬做出来 踢我一下。
levelworm
2021-08-03 23:15:59 +08:00
没用过 MySQL,看了下文档:
https://dev.mysql.com/doc/refman/8.0/en/multiple-column-indexes.html

>MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on. If you specify the columns in the right order in the index definition, a single composite index can speed up several kinds of queries on the same table.

感觉和索引中列的顺序有关,比如下面的例子给了:
如果对 last_name,first_name 建立联合索引,但是仅仅查询 first_name,就不会用到这个索引。感觉说的和你一样啊,只要是最左前缀匹配就可以了,除非他建立索引的顺序不是 a, b, c 。
mainjzb
2021-08-03 23:16:50 +08:00
范围和排序不能同时索引
shalk
2021-08-03 23:27:41 +08:00
如果表就只有 a,b,c 所以索引也是 a,b,c 会走索引,而且索引覆盖
lxy42
2021-08-03 23:28:44 +08:00
例如这组数据就不可以用到索引:(1,3,1), (1,3,3), (1,3,5), (1,4,2), (1,4,5), (1,4,5)
pengtdyd
2021-08-03 23:33:19 +08:00
面试造火箭,这种问题在实际开发中有用?
MOONLIGHTT
2021-08-03 23:37:07 +08:00
第一题是因为 order,如果是 order by a, b 的话就能走索引了
MOONLIGHTT
2021-08-03 23:38:02 +08:00
第二题一般是先更新数据库再删除缓存
sagaxu
2021-08-03 23:51:03 +08:00
联合索引,查询匹配到第一个非=结束,有非=时排序就用不到索引了。即使全部是=,若区分度不够高,仍然不会走索引。所以走不走索引,是个玄学,要看具体数据分布和规模以及查询条件。
ZeawinL
2021-08-04 00:46:53 +08:00
来学习下 MySQL Innodb 索引是怎么存储数据的
https://someexp.com/post/mysql-learning/
yinusxxxx
2021-08-04 06:04:55 +08:00
数据量小的话因为回表有成本可能不走索引,直接读更快。数据倾斜,如果区分度不高也可能不走索引比如 a 只有 2 个值,b 只有 3 个值之类的,不走索引,如果 where 条件里查出来过滤程度不高也不会走索引,因为回表成本高,DBMS 会通过采样和直方图 histogram 的方式判断数据分布情况,这里会有一个问题,采样数据直方图不是同步更新的,导致可以走索引反而不走索引或者选错索引的情况。还有一些情况暂时没想到,如果数据量够大,区分度够高会走索引。另外有的数据库支持 index skip scan,即使查询条件不符合最左索引也可以部分使用索引,走不走索引跟 order by 没什么关系,只是如果索引的顺序跟 order by 是一样的可以减少排序。order by 是在所有数据都 select 之后的操作了。
yinusxxxx
2021-08-04 06:13:03 +08:00
更正一下,order by 不用排序也算是用上索引了,在你的例子里 order by 是用不上索引的
yidinghe
2021-08-04 08:11:20 +08:00
问题出在 c 字段排序。想象索引是一棵树,通过 a 和 b 条件可以直接在树中确定一个子树范围,但是在这个范围内索引仍然是按照 a,b,c 的顺序组织的,只有按照这个顺序排序才能用到索引,直接 c 字段排序会导致需要获取子树中的所有记录,整个重新排序。
love2020
2021-08-04 08:35:53 +08:00
这世界哪有啥一致,都是妥协罢了。
wugq
2021-08-04 08:40:14 +08:00
为什么我觉得问题 1 可以用到索引。a 如果是范围查找只能用到 (A);这里 a 是等值,b 是范围,应该可以用到(A, B)啊。 因为 b 是范围查找,所以 c 没办法用到,需要找到数据后再对 c 排序。
wugq
2021-08-04 08:42:22 +08:00
还是说数据少的时候避免回表会直接走聚簇索引?
chenshun00
2021-08-04 08:56:05 +08:00
先反问一波是强一致性还是最终一致性,如果是强一致性,那就解决不了 (引入缓存的都无法解决强一致性,有可以解决的方式,希望大佬下边说一说)。最终一致性可以按照先 MySQL 在 Redis 搞。
1018ji
2021-08-04 09:00:24 +08:00
我也觉得会走索引,这个 order by 可能是 filesort
chenshun00
2021-08-04 09:03:20 +08:00
```mysql
CREATE TABLE `test_table` (
`action` varchar(64) NOT NULL,
`projectId` int(11) NOT NULL COMMENT 'yapi 项目 ID',
`projectName` varchar(32) NOT NULL COMMENT '项目名字',
`catId` int(11) NOT NULL COMMENT 'API 分类 ID',
`catName` varchar(64) NOT NULL COMMENT 'API 分类名字',
`apiDesc` varchar(512) NOT NULL COMMENT 'API 分类描述',
`title` varchar(64) NOT NULL COMMENT 'API 标题',
`path` varchar(64) NOT NULL COMMENT 'http 请求路径',
`method` varchar(12) NOT NULL COMMENT 'api 请求方法',
`upTime` datetime NOT NULL DEFAULT '2020-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`addTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
`version` varchar(32) NOT NULL COMMENT '版本',
`status` varchar(16) NOT NULL COMMENT 'api 状态(上线 /下线)',
`fullinfo` text NOT NULL COMMENT 'API fullinfo 信息',
`visibility` tinyint(4) NOT NULL DEFAULT '0',
`session` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`action`),
KEY `test_table_projectId_catId_path_index` (`projectId`,`catId`,`path`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
```

desc select * from test_table where projectId = '11111' and catId >2 order by path;


key: test_table_projectId_catId_path_index
extra: Using index condition; Using filesort

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/793477

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX