关于 mysql 索引讨论

2020-03-16 15:19:18 +08:00
 brader

SELECT SUM(number) FROM transfer WHERE username = 888888 AND type = 818 LIMIT 1;

transfer表数据量较大,类似语句经常使用,但是username字段和type字段 也经常会出现单独使用的情况。

那么关于索引建立: 是否应该放弃复合索引?转而给usernametype单独建立索引? number作为统计字段,应该给它建立索引吗?,是否利大于弊?(number建立索引考虑:能减少回表操作,上述语句能触发索引覆盖,这点是个人见解,不知道是否理解的正确)

有大神指点下吗?

4065 次点击
所在节点    MySQL
24 条回复
scriptB0y
2020-03-16 20:18:16 +08:00
在没 Explain 的情况下,我尝试分析下:

- username, type, number 索引,针对第一条 SELECT 语句,这样应该光在索引里面就得到结果了;
- type 单独建索引,虽然用 type 查的话区别不大了,filter 会消耗大头的时间, 但是有跟没有还是应该有区别的;
- username 不需要建索引,使用 username 可以走第一条索引;

最靠谱的办法是看 Explain 分析一下,第二靠谱的办法是压测一下。不同的数据库的优化器可能有不同的选择。

分享下 https://use-the-index-luke.com/sql/table-of-contents 看完这个对索引基本就明白了。

嫌长可以看下我的笔记:

1. https://www.kawabangga.com/posts/3893
2. https://www.kawabangga.com/posts/3915
qyvlik
2020-03-16 21:43:45 +08:00
可以看看 索引覆盖 和 索引下推 这两个特性,mysql5.6 或以上版本有。MariDB 就不太清楚。

可以做个简单的统计,然后按照查询频次,选择建立合适的索引。例如:
1. 查询条件单独使用 username 的次数
2. 查询条件单独使用 type 的次数
3. 其他条件

此外可以考虑加个时间戳,这样就可以按照时间段,分段存储统计过的数据,减少不必要的查询。
sansanhehe
2020-03-17 09:25:53 +08:00
@brader mysql 查询时有多个索引只选择最优的一个,所以联合索引生效的情况下,单独的 number 索引应该是不生效的
Aresxue
2020-03-17 13:21:45 +08:00
6 楼正解, 只建立一个(username,type)的联合索引即可

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

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

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

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

© 2021 V2EX