以 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 的实现吗?
1
DovaKeen 2019-05-15 15:55:49 +08:00
不太熟悉 mongo 的联合索引,但是我记得在 mysql 的联合索引( B 树索引)里,对于顺序是有要求的,比如索引是以 A, B, C 的顺序建立,那么只有查询时限定条件的顺序也是这个顺序,不能出先逆序,才能获得速度的提升。
第二个的话,mongodb 似乎不会在一次查询中使用两次索引吧? |
2
liprais 2019-05-15 16:14:06 +08:00
1.对于 in-list 的优化有两种方法,一种是把 in-list 里面的东西做成一张表来关联,另外一种是重写成一堆 or ,看代价。能不能用索引如果是 B 树的话要符合最左前缀的原则
2 就是 index lookup 呗,一般数据库都支持的。复合索引能不能用 index lookup 要具体看数据库的实现。 |
3
xkeyideal 2019-05-15 17:31:56 +08:00
使用 B+树实现的索引,都要遵循最左原则。
mongodb 也有 explain 可以查看 sql 的执行规则与情况,可以参考一下。 mongodb 在查询的时候可以指定使用使用哪个索引,mongodb 目前的 sql 优化做的比 mysql 还是差挺多,自己 explain 查看一下执行计划,如果认为有问题,可以使用此方法。 至于数据分片,不一定要使用 mongos,可以自己构建数据路由的程序,这样可控度会比较高。 |