【问题标题】:How to find queries not using indexes or slow in mongodb如何在 mongodb 中查找不使用索引或速度慢的查询
【发布时间】:2013-08-29 09:19:41
【问题描述】:

有没有办法在 mongodb 中找到不使用索引或速度慢的查询?在 MySQL 中,可以通过配置文件中的以下设置:

log-queries-not-using-indexes = 1
log_slow_queries = /tmp/slowmysql.log

【问题讨论】:

    标签: performance mongodb mongodb-query


    【解决方案1】:

    MongoDB 中的等效方法是使用query profiler 来跟踪和诊断慢查询。

    为数据库启用分析后,慢速操作将写入 system.profile 上限集合(默认大小为 1Mb)。您可以使用slowms parameter 调整慢速操作的阈值(默认为 100 毫秒)。

    【讨论】:

    • 或者您可以执行以下操作:mongo localhost:27017 并在控制台中写入 db.setProfilingLevel(2,10) - 这将在日志中打印所有执行时间超过 10 毫秒的查询
    • @Bestmacros 是的,这就是答案中建议的“查询分析器”。
    【解决方案2】:

    首先,您必须设置分析,指定所需的日志级别。三个选项是:

    • 0 - 注销
    • 1 - 记录慢速查询
    • 2 - 记录所有查询

    您可以通过使用 --profile 选项运行您的 mongod 守护进程来做到这一点:

    mongod --profile 2 --slowms 20

    这样,日志将被写入system.profile 集合,您可以在该集合上执行如下查询:

    • 查找某个集合中的所有日志,按时间戳升序排列:

    db.system.profile.find( { ns:/<db>.<collection>/ } ).sort( { ts: 1 } );

    • 查找超过 5 毫秒的查询日志:

    db.system.profile.find( {millis : { $gt : 5 } } ).sort( { ts: 1} );

    【讨论】:

      【解决方案3】:

      您可以使用以下两个 mongod 选项。第一个选项使不使用索引的查询失败(仅 V 2.4),第二个记录查询慢于一些毫秒阈值(默认为 100 毫秒)

      --notablescan
      
      Forbids operations that require a table scan.
      
      --slowms <value>
      
      Defines the value of “slow,” for the --profile option. The database logs all slow queries to the log, even when the profiler is not turned on. When the database profiler is on, mongod the profiler writes to the system.profile collection. See the profile command for more information on the database profiler.
      

      【讨论】:

      • 那么在提供了 --notablescan 的情况下——查询会被 mongod 拒绝吗?会登录到system.profile集合吗?
      • --notablescan的情况下会返回一个错误,你会在日志中看到query db.coll query: { whatever } ntoreturn:0 keyUpdates:0 exception: table scans not allowed: db.coll这样的东西
      • 请注意,您应该只在开发环境中使用 {{--notablescan}}。有许多简单的管理任务需要表扫描(即查看集合列表或更新非索引字段),因此启用此选项可能会产生意想不到的后果。
      • 我会认为这两个选项都是 ev envo 中的错误选项,显然您想从应用程序/控制台中切换日志级别并使用它来记录某些查询,而不必重置守护程序为了做这种事情,无表扫描也不会记录这些查询,而是停止它们
      • @Sammaye 如果你从一开始就在开发中拥有--notablescan,则无需记录任何内容并强制开发使用索引
      【解决方案4】:

      您可以使用命令行工具mongotail 从控制台中的分析器中读取日志,并且格式更易读。

      首先激活分析器并设置阈值(以毫秒为单位),以便分析器认为操作很慢。在以下示例中,名为“sales”的数据库的阈值设置为 10 毫秒:

      $ mongotail sales -l 1
      Profiling level set to level 1
      $ mongotail sales -s 10
      Threshold profiling set to 10 milliseconds
      

      然后,在“实时”中查看慢查询,以及一些额外的信息,例如每个查询所用的时间,或者需要“遍历”多少个注册表才能找到特定结果:

      $ mongotail sales -f -m millis nscanned docsExamined
      2016-08-11 15:09:10.930 QUERY   [ops] : {"deleted": {"$exists": false}, "prod_id": "367133"}. 8 returned. nscanned: 344502. millis: 12
      2016-08-11 15:09:10.981 QUERY   [ops] : {"deleted": {"$exists": false}, "prod_id": "367440"}. 6 returned. nscanned: 345444. millis: 12
      ....
      

      【讨论】:

      • 不错的工具!我能够快速设置它,并使用生产数据库的本地副本获得一些良好的基准。
      【解决方案5】:

      如果有人从谷歌那里结束这个老问题,我发现explain 确实帮助我修复了我可以看到导致日志中的COLLSCANs 的特定查询。

      例子:

      db.collection.find().explain()

      这会让您知道查询是使用COLLSCAN(基本光标)还是index(BTree)等等。

      https://docs.mongodb.com/manual/reference/method/cursor.explain/

      【讨论】:

        【解决方案6】:

        虽然您显然可以使用 Profiler,但 Mongo DB 的一个非常简洁的功能是我真正爱上它的原因是 Mongo DB MMS。 花费不到 60 秒,可以在任何地方进行管理。我相信你会喜欢它。 https://mms.mongodb.com/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-17
          • 1970-01-01
          • 2016-08-28
          • 1970-01-01
          • 2012-01-05
          • 2012-07-07
          • 2022-11-02
          • 1970-01-01
          相关资源
          最近更新 更多