mongoDB's Query Optimizer [ not CBO ]

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:
   mongodb 的优化器为每个客户端提交的查询产生所有的执行计划后并行执行所有的执行计划,最先执行完毕的执行计划将被选出并缓存起来,没有执行完的执行计划将丢弃。下次执行时mongoDB将匹配缓存中的执行计划。
   在mongoDB中,被选出的较优的执行计划,在后期的执行中如果不优了(如因为数据的变更或者查询传入参数的改变,没有达到预期的执行效率)怎么办?mongoDB自动感知到一个执行计划已经不优了的时候,将重新选择并缓存更优的执行计划。
   mongoDB的这种不是基于cost和统计信息的优化选择器有一定的好处,但是也给数据库带来一定的负担。哪个好哪个不好确实不好定论。
   使用CBO的数据库如PostgreSQL,在对数据表进行大批量操作后通常建议重新analyze该表(即收集统计信息)。Oracle也是如此,如果统计信息不正确将导致数据库选择较劣的执行计划给数据库带来严重负担。
    而mongoDB没有统计信息当然也谈不上analyze,如果大批量更新数据导致执行计划不对的话按照mongoDB的说法应该下一次执行就会正常了。但是对于传入参数不一样导致的执行计划不对是不是会出现执行计划紊乱呢?解决办法除了重业务层隔离数据以外,使用非绑定变量也行。不过会给CPU带来严重负担。

【原文】

The MongoDB query optimizer generates query plans for each query submitted by a client.  These plans are executed to return results. Thus, MongoDB supports ad hoc queries much like say, MySQL.

The database uses an interesting approach to query optimization though. Traditional approaches (which tend to be cost-based and statistical) are not used, as these approaches have a couple of problems.

First, the optimizer might consistently pick a bad query plan.  For example, there might be correlations in the data of which the optimizer is unaware.  In a situation like this, the developer might use a query hint.

Also with the traditional approach, query plans can change in production with negative results.  No one thinks rolling out new code without testing is a good idea.  Yet often in a production system a query plan can change as the statistics in the database change on the underlying data.  The query plan in effect may be a plan that never was invoked in QA.  If it is slower than it should be, the application could experience an outage.

The Mongo query optimizer is different.  It is not cost based -- it does not model the cost of various queries.  Instead, the optimizer simply tries different query plans and learn which ones work well.  Of course, when the system tries a really bad plan, it may take an extremely long time to run.  To solve this, when testing new plans, MongoDB executes multiple query plans in parallel.  As soon as one finishes, it terminates the other executions, and the system has learned which plan is good. This works particularly well given the system is non-relational, which makes the space of possible query plans much smaller (as there are no joins).

Sometimes a plan which was working well can work poorly -- for example if the data in the database has changed, or if the parameter values to the query are different.  In this case, if the query seems to be taking longer than usual, the database will once again run the query in parallel to try different plans.

This approach adds a little overhead, but has the advantage of being much better at worst-case performance.

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
SQL 移动开发 算法
MySQL 8.0.23 Hypergraph Join Optimizer代码详解
MySQL Join MySQL本身没有常规意义上的执行计划,一般情况就是通过JOIN和QEP_TAB这两个结构组成。QEP_TAB 的全称是Query Execution Plan Table,这个“Table“可以是物理表、内存表、常量表、子查询的结果表等等。作为整个单独JOIN执行计划载体之前还承担着整个执行路径的调用和流转,但是从8.0.20后,全面的生成了独立的
1525 0
MySQL 8.0.23 Hypergraph Join Optimizer代码详解
|
SQL NoSQL MySQL
MongoDB 执行计划 & 优化器简介 (上)
最近,由于工作需求去了解一下Query是如何在MongoDB内部进行处理,从而丢给存储引擎的。里面涉及了Query执行计划和优化器的相关代码,MongoDB整体思路设计的干净利落,有些地方深入挖一下其实还是能有些优化点的。本文会涉及一条Query被parse之后一路走到引擎之前,都做了那些事情,分析基于MongoDB v3.4.6代码。由于篇幅过长,文章分为上下两篇,分别介绍执行计划 & 优化器和
3631 0
|
6月前
|
NoSQL MongoDB
08 MongoDB - 数据查询(Limit 与 Skip)
08 MongoDB - 数据查询(Limit 与 Skip)
42 0
|
10月前
|
关系型数据库 PostgreSQL
PostgreSQL执行计划explain
PostgreSQL执行计划explain
85 0
|
10月前
|
算法 关系型数据库 PostgreSQL
PostgreSQL/GreenPlum Merge Inner Join解密
PostgreSQL/GreenPlum Merge Inner Join解密
54 0
PostgreSQL/GreenPlum Merge Inner Join解密
|
人工智能 分布式计算 前端开发
更高效的Cascades优化器 - Columbia Query Optimizer
在较早的文章中介绍了些Volcano/Cascades优化器框架的设计理念和实现思路,基本是基于论文的解读:VolcanoCascades虽然cascades号称目前最为先进的优化器搜索框架,但不得不说这2篇paper的内容,实在是让人看起来有些吃力。尤其是后篇,说是从工程实现的角度来描述,但讲解的不够详尽,而且有些地方既模糊又抽象。此外工业界并没有一款优化器是完全基于paper的框架去实现的,这
1504 0
更高效的Cascades优化器 - Columbia Query Optimizer
|
存储 SQL JSON
MySQL Case-通过optimizer_trace看MySQL优化器行为
我们在日常维护数据库的时候,如果遇到慢语句查询的时候,我们一般会怎么做?执行EXPLAIN去查看它的执行计划?是的。我们经常会这么做,然后看到执行计划展示给我们的一些信息,告诉我们MySQL是如何执行语句的。但是,执行计划往往只给我们带来了最基础的分析信息,比如是否有使用索引,还有一些其他供我们分析的信息,比如使用了临时表、排序等等。
387 0
|
SQL 存储 弹性计算
PostgreSQL sharding extensino citus 优化器 Query Processing 之 - Subquery/CTE Push-Pull Execution
标签 PostgreSQL , citus , sharding , push , pull , 优化器 背景 citus 是postgresql的sharding 开源中间件,2018年被微软收购,插件依旧开源。 在处理非常复杂的SQL时,CITUS使用推拉模型,支持跨节点的数据交换,用以处理复杂SQL。 中间结果的push,pull过程: push : shard ->
247 0
|
SQL Oracle 关系型数据库
PostgreSQL JOIN limit 优化器 成本计算 改进 - mergejoin startup cost 优化
标签 PostgreSQL , join , limit , startup cost , cbo , 优化器改进 背景 PostgreSQL limit N的成本估算,是通过计算总成本A,以及估算得到的总记录数B得到: (N/B)*A 大概意思就是占比的方法计算 对于单表查询...
1169 0