关于索引和查询的几个问题,网上没找到答案

2019-05-15 15:41:13 +08:00
 rrfeng

以 MongoDB 为例(相同问题可以扩展导其他 DB,当然各种实现有所不同)

问题 1:假设有一个表,两个字段 a, b,建立联合索引,然后查询 {a: x, b: {$in: [y1, y2, y3]} },通常我们知道应该建立 a+b 的联合索引。那么如果使用 b+a 的联合索引,效率上会差多少?如果以 b 或者 b+a 索引进行分片,那么 SQL 分析器会不会将 $in 拆分出来分别路由然后查询后汇总?

问题 2:假设我们以 a+c 索引分片,额外建立索引 b+a,那么在查询 {a:x, b:y} 的时候,路由索引(分片索引)会影响查询计划的索引吗?也就是说这个查询是否可以在路由的时候根据 a+c(分片索引)找到对应的分片,然后在分片上检索的时候使用 b+a 索引?

看起来都是 SQL 分析器实现上的问题,也就是理论上可以这么做但是实际有没有做各家不同? TiDB 的同学是怎么做的呢?对于 mongos 有了解的同学知道 mongos 的实现吗?

7414 次点击
所在节点   NoSQL
4 条回复
DovaKeen
2019-05-15 15:55:49 +08:00
不太熟悉 mongo 的联合索引,但是我记得在 mysql 的联合索引( B 树索引)里,对于顺序是有要求的,比如索引是以 A, B, C 的顺序建立,那么只有查询时限定条件的顺序也是这个顺序,不能出先逆序,才能获得速度的提升。
第二个的话,mongodb 似乎不会在一次查询中使用两次索引吧?
liprais
2019-05-15 16:14:06 +08:00
1.对于 in-list 的优化有两种方法,一种是把 in-list 里面的东西做成一张表来关联,另外一种是重写成一堆 or ,看代价。能不能用索引如果是 B 树的话要符合最左前缀的原则
2 就是 index lookup 呗,一般数据库都支持的。复合索引能不能用 index lookup 要具体看数据库的实现。
xkeyideal
2019-05-15 17:31:56 +08:00
使用 B+树实现的索引,都要遵循最左原则。
mongodb 也有 explain 可以查看 sql 的执行规则与情况,可以参考一下。
mongodb 在查询的时候可以指定使用使用哪个索引,mongodb 目前的 sql 优化做的比 mysql 还是差挺多,自己 explain 查看一下执行计划,如果认为有问题,可以使用此方法。
至于数据分片,不一定要使用 mongos,可以自己构建数据路由的程序,这样可控度会比较高。
rrfeng
2019-05-15 18:40:50 +08:00
@DovaKeen
索引顺序有要求,但是在写查询条件的时候不要求啊,比如你写 where a=1 and b=2,实际上可以使用 b_a 索引的。我的问题是对于 where a=1 and b in [1,2,3] 这种情况下,对于 B+ 索引来说肯定是 a_b 效率高,因为定位到 a 即可。b_a 的话需要跳 N 次查询。
这个情况在分片的情况下就有不同了,如果按 b 分片,那么对于每个片来说可能是一个 a=1 and b=x 的简单查询,所以使用 b_a 索引可能会提高效率。

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

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

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

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

© 2021 V2EX