Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-60718

Access of sub-fields is slow in SBE queries

    • Type: Icon: Bug Bug
    • Resolution: Gone away
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • ALL
    • QE 2022-10-03
    • 0

      Summary: accessing a sub-field is ~20-30% slower in SBE compared to the classical engine.

       

      Create a collection with 10^6 documents like this: { a: Random.randInt(10), e: { x: Random.randInt(10)}}

      Let the collection's namespace be "sbe-perf.LS", run against it the following benchmark:

      benchRun({parallel: 1, seconds: 5, ops: [{op:"find", ns:"sbe-perf.LS", query:{"e.x":7}, readCmd: true}]})

      results:

      "queryLatencyAverageMicros" : 678104.625,
      "totalOps" : NumberLong(8),
      "totalOps/s" : 1.4746812891147691,

      The results of the benchmark in classical engine are:

      "queryLatencyAverageMicros" : 481276,
      "totalOps" : NumberLong(11),
      "totalOps/s" : 2.0777796016065393,

      The top CPU consumers in SBE mode:

      + 23.49% mongod [.] mongo::sbe::vm::ByteCode::runInternal
      + 6.51% mongod [.] mongo::sbe::ProjectStage::getNext
      + 5.20% libc-2.27.so [.] __strlen_avx2
      + 5.06% mongod [.] __wt_btcur_next_prefix
      + 4.86% mongod [.] mongo::sbe::vm::ByteCode::run
      + 3.08% mongod [.] mongo::sbe::vm::ByteCode::getField
      + 2.85% mongod [.] __unpack_read
      + 2.73% mongod [.] __wt_cursor_get_valuev
      + 2.55% mongod [.] mongo::WiredTigerRecordStoreCursorBase::next
      + 2.37% mongod [.] mongo::sbe::TraverseStage::traverse
      + 2.16% mongod [.] __wt_cursor_get_keyv
      + 2.09% mongod [.] mongo::sbe::ScanStage::getNext
      + 1.91% mongod [.] mongo::sbe::bson::advance
      + 1.86% mongod [.] __wt_txn_read
      + 1.83% mongod [.] mongo::sbe::ProjectStage::open
      + 1.61% mongod [.] mongo::sbe::LimitSkipStage::getNext
      + 1.52% mongod [.] mongo::ElapsedTracker::intervalHasElapsed
      + 1.49% mongod [.] mongo::sbe::LimitSkipStage::open

      The generated plan:

      [1] filter {fillEmpty (s12, false)}
      [1] traverse s12 s11 s6 [s4, s5, s7] {s12 || s11} {s12}
      from
       [1] project [s7 = fillEmpty (isArray (s6), false)]
       [1] project [s6 = getField (s4, "e")]
       [1] scan s4 s5 none none none none [] @"c494dfc1-7ed7-45e7-a46d-b253a1e532db" true false
      in
       [1] project [s11 = fillEmpty (s10, false)]
       [1] traverse s10 s9 s8 {s10 || s9} {s10}
       from
       [1] project [s8 = getField (s6, "x")]
       [1] filter {! s7 || isObject (s6)}
       [1] limit 1
       [1] coscan
       in
       [1] project [s9 = fillEmpty (s8 == 7, false)]
       [1] limit 1
       [1] coscan

      Flamegraph is attached.

            Assignee:
            mihai.andrei@mongodb.com Mihai Andrei
            Reporter:
            irina.yatsenko@mongodb.com Irina Yatsenko (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated:
              Resolved: