การอ้างอิงการดำเนินการค้นหา

หน้านี้อธิบายเอาต์พุตของการค้นหาที่เรียกใช้ด้วย Query Explain หากต้องการดูวิธีเรียกใช้การค้นหาด้วย Query Explain โปรดดู วิเคราะห์การเรียกใช้การค้นหาด้วย Query Explain

แนวคิดสำคัญ

แนวคิดและคำที่ใช้กันโดยทั่วไปต่อไปนี้จะใช้ตลอดทั้งแผนผังการเรียกใช้

แถวและระเบียน

คำว่าแถว และ ระเบียน ใช้เพื่ออ้างอิงเอกสารหรือรายการดัชนีโดยทั่วไป

ตัวแปร

$ หมายถึงตัวแปร ซึ่งสร้างขึ้นหรือ อ้างอิงในแผนผังการเรียกใช้ เช่น $foo_1 โดยทั่วไปแล้วตัวแปรเหล่านี้จะใช้เพื่อ อ้างอิงเนื้อหาของเอกสารหรือค่าของนิพจน์ที่ประเมิน ระหว่างการเรียกใช้การค้นหา

ตัวแปรภายในต่อไปนี้อาจปรากฏในโหนดการเรียกใช้

  • $__key__ - คีย์คือตัวระบุภายในสำหรับเอกสาร ซึ่งเป็นตัวระบุที่ไม่ซ้ำกันแบบสัมบูรณ์ที่มีโปรเจ็กต์ ฐานข้อมูล และเส้นทางแบบเต็มของเอกสาร
  • $__id__ - รหัสคือตัวระบุที่ไม่ซ้ำกันสำหรับเอกสารภายในคอลเล็กชัน ซึ่งไม่ซ้ำกันภายในคอลเล็กชันเดียว
  • $rid - รหัสแถวคือตัวระบุภายในสำหรับเอกสารในพื้นที่เก็บข้อมูล ซึ่งไม่ซ้ำกันภายในคอลเล็กชันเดียว

ลองพิจารณาตัวอย่างที่ใช้โหนด Compute เพื่อคำนวณ __id__ จากเอกสาร __key__

Compute
    |  $__id__1: _id($__key__)
    |  records returned: 1

ข้อจำกัดและช่วง

โหนดการสแกนบางโหนดใช้แอตทริบิวต์ constraints และ ranges เพื่ออธิบายช่วงของค่าที่จะสแกน แอตทริบิวต์เหล่านี้ใช้รูปแบบแผนผังช่วงซึ่งมีรายการค่า ค่าเหล่านี้สอดคล้องกับรายการคีย์ที่เรียงลำดับซึ่งปรากฏในคำจำกัดความของดัชนี ตัวอย่างเช่น ช่วงแรกที่ปรากฏ ในแผนผัง ซึ่งในที่นี้คือ (1..5] จะสอดคล้องกับข้อจำกัดของคีย์แรก ซึ่งในที่นี้คือ a ในรายการคีย์ที่เรียงลำดับ

| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
               |----(1..5]
                    |----[1L]

การเยื้องแต่ละระดับจะระบุข้อจำกัดที่ใช้กับคีย์ถัดไปในรายการ วงเล็บเหลี่ยมแสดงถึงช่วงที่รวมค่าขอบเขต ส่วนวงเล็บกลมแสดงถึงช่วงที่ไม่รวมค่าขอบเขต ในกรณีนี้ ข้อจำกัดจะแปลเป็น 1 < "a" <= 5 และ "b" = 1

ในตัวอย่างต่อไปนี้ที่มีหลายสาขาสำหรับ a, ข้อจำกัดจะสอดคล้องกับ 1 < a <= 5 OR a = 10

| constraints: /
               |----(1L, 5L]
               |----[10L]

ตัวแปรคีย์

ในโหนดการสแกนบางโหนด (เช่น SequentialScan) จะมีทั้งรายการคีย์เป็นส่วนหนึ่งของแอตทริบิวต์ index และแอตทริบิวต์ keys แยกต่างหากในโหนด Scan แอตทริบิวต์ keys ในโหนด Scan จะระบุชื่อตัวแปรของคีย์แต่ละรายการในคำจำกัดความของดัชนีตามลำดับ ตัวแปรสามารถใช้เพื่ออ้างอิงค่ารันไทม์ของช่องที่สแกนในแผนผังการเรียกใช้

ในตัวอย่างต่อไปนี้ ค่าของช่อง user สำหรับเอกสารปัจจุบัน จะแมปกับตัวแปร $user_1 และค่าของ date_placed จะแมปกับ $date_placed_1

index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]

โหนดการเรียกใช้

แผนผังการเรียกใช้การค้นหาอาจมีโหนดต่อไปนี้

SeekingScan

แสดงถึงการสแกนแบบไดนามิกที่แถวที่แสดงผลอาจไม่ได้อยู่ในช่วงลำดับเดียวของดัชนี และต้องทำการสแกนที่แตกต่างกันหลายครั้งเพื่อให้ตรงตามการค้นหา

ตัวอย่างเช่น การค้นหาที่ a มีอยู่และ b เท่ากับ 1 ซึ่งทำงานบน ดัชนีของ ["a" ASC, "b" ASC] จะต้องสแกนและแสดงผลช่วงที่แยกต่างหาก ซึ่งอาจไม่ใช่ช่วงลำดับสำหรับค่าที่แตกต่างกันแต่ละค่าของ a วิธีนี้มีประสิทธิภาพมากกว่า TableScan แบบเต็ม แต่มีประสิทธิภาพน้อยกว่า SequentialScan รายการเดียวในดัชนีคอมโพสิต ["b" ASC, "a" ASC]

• SeekingScan
| constraints: /
               |----(-∞..+∞)
                    |----[1L]
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, quantity ASC, __key__ ASC]
| keys: [user ASC, quantity ASC, __key__ ASC]
| properties: Selection { user }
| records returned: 1
| records scanned: 1

SequentialScan

แสดงถึงการสแกนช่วงลำดับคงที่ของแถวในพื้นที่เก็บข้อมูลที่สามารถทำได้ในการดำเนินการอ่านครั้งเดียว

key ordering length หมายถึงจำนวนคีย์ที่ต้องเก็บรักษาและแสดงผลตามลำดับคีย์เดิม สำหรับสคีมา [k1, k2, k3] ความยาวการเรียงลำดับคีย์เป็น 0 หมายความว่าการสแกนสามารถแสดงผลตามลำดับใดก็ได้ 1 หมายความว่าเรียงตาม k1 แต่แถวที่มีค่า k1 เดียวกันอาจแสดงผลตามลำดับใดก็ได้ 3 จะแสดงผลเอกสารตามลำดับที่เรียงอย่างถูกต้อง

• SequentialScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| key ordering length: 3
| keys: [user ASC, date_placed ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1

UniqueScan

แสดงถึงการสแกนช่วงลำดับคงที่ของแถวในพื้นที่เก็บข้อมูลพร้อมการขจัดข้อมูลซ้ำของแถวในหน่วยความจำ

• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [user ASC, date_placed ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
          |----(-∞..+∞)
| records returned: 1
| records scanned: 1

IndexSeek

แสดงถึงการสแกนแบบไดนามิกที่แถวที่แสดงผลอาจมีการกำหนดพารามิเตอร์ตามข้อมูลรันไทม์และอาจไม่ได้อยู่ในช่วงลำดับเดียวของดัชนี และอาจทำการสแกนที่แตกต่างกันหลายครั้งเพื่อให้ตรงตามการค้นหา

ตัวอย่างเช่น การค้นหาที่ user เท่ากับ $user_id และ date_placed เท่ากับ "2025-08-10" ซึ่งทำงานบนดัชนี ["user" ASC, "date_placed" ASC] จะ ใช้ค่าของตัวแปร $user_id ในรันไทม์และข้อจำกัด "2025-08-10" ใน date_placed เพื่อจำกัดช่วงการสแกน

• IndexSeek
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| fields: [$user_1 ASC, $date_placed_1 ASC, $rid ASC]
| key: $key_1
| filter: equal($user_1, $user_id) AND equal($date_placed_1, "2025-08-10")
| records returned: 1
| records scanned: 1

เรียกข้อมูล

รวมตัวระบุของแถวที่ระบุเข้ากับเนื้อหาแถวจริงจากพื้นที่เก็บข้อมูลหลัก ต้องใช้ Fetch หากโหนดระดับบน (หรือผลการค้นหาสุดท้าย) ต้องการชุดย่อยของช่องจากเอกสาร

• Fetch
|  order: PRESERVE_INPUT_ORDER
|  peak memory usage: 4.00 KiB (4,096 B)
|  properties: *
|  records returned: 1

LookupById

ทำการรวมโดยการค้นหาเอกสารในคอลเล็กชันภายนอกตามรหัส ระบบจะดึงข้อมูลรหัสที่จะค้นหาจากช่องในเอกสารอินพุต และเพิ่มผลการค้นหาเป็นช่องใหม่ในเอกสารอินพุต

• LookupById
|  local_field: $localField_1
|  foreign_datasource: (default)#/**/foreign
|  output: $output_1

TableScan

การสแกนคอลเล็กชันแบบเต็มโดยไม่เรียงลำดับ ใช้เมื่อเรียกใช้การค้นหาโดยไม่มีดัชนีที่เชื่อมโยง

ลำดับอาจเป็น STABLE หรือ UNDEFINED โดย STABLE หมายถึงการเรียงลำดับแบบกำหนดได้

• TableScan
|  order: STABLE
|  properties: *
|  records returned: 1
|  records scanned: 1
|  source: (default)#/**/collection

NestedLoopJoin

ทำการรวมระหว่างชุดข้อมูล 2 ชุด (ซ้ายและขวา) โดยการวนซ้ำแต่ละแถวของอินพุตด้านซ้าย และสำหรับแต่ละแถวด้านซ้าย ให้สแกนอินพุตด้านขวาเพื่อหาแถวที่ตรงกันตาม join_condition

join_type ระบุประเภทการรวม ตัวอย่างเช่น LEFT_OUTER หมายความว่าแถวทั้งหมดจากอินพุตด้านซ้ายจะรวมอยู่ในเอาต์พุตอย่างน้อย 1 ครั้ง หากแถวด้านซ้ายไม่ตรงกับแถวใดๆ ในอินพุตด้านขวาตาม join_condition แถวด้านซ้ายจะยังคงรวมอยู่ด้วยค่า Null สำหรับคอลัมน์จากอินพุตด้านขวา

• NestedLoopJoin
|  join_type: LEFT_OUTER
|  join_condition: equal($left, $right)
|
└── • left tree
|     ...
└── • right tree
      ...

HashAggregate

การใช้งานการดำเนินการรวมที่ใช้แฮช ต้องทำให้กลุ่มทั้งหมดเป็นจริงในหน่วยความจำก่อนแสดงผล และต้องไม่เกินขีดจำกัดหน่วยความจำของการค้นหา

• HashAggregate
|  aggregations: [sum($b_1) AS total]
|  groups: [$a_1]
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 0

StreamAggregate

โหนดรวมเฉพาะทางซึ่งเก็บสถานะไว้สำหรับกลุ่มเดียวในแต่ละครั้ง ซึ่งช่วยลดการใช้งานหน่วยความจำสูงสุด ใช้เมื่อโหนดย่อยพื้นฐานจะแสดงผลกลุ่มตามลำดับ เช่น เมื่อจัดกลุ่มตามค่าที่แตกต่างกันของช่องขณะใช้ดัชนีในช่องนั้น

• StreamAggregate
|  keys: [foo ASC, bar ASC]
|  properties: Selection { baz }
|  aggregations: [$sum($foo_1) AS baz]

MajorSort

ทำการดำเนินการเรียงลำดับในชุดพร็อพเพอร์ตี้คงที่ ทำให้ระเบียนทั้งหมด เป็นจริงในหน่วยความจำพร้อมกันและแสดงผลค่าที่เรียงลำดับตามลำดับ โดยขนาดของชุดการเรียงลำดับ จะจำกัดตาม ขีดจำกัดหน่วยความจำของการค้นหา

เมื่อมีการระบุขีดจำกัดในภายหลัง ระบบจะใช้อัลกอริทึมการเรียงลำดับ k อันดับแรกเพื่อลดการใช้งานหน่วยความจำ ซึ่งจะช่วยให้สามารถทำการเรียงลำดับในชุดระเบียนขนาดใหญ่ได้ตราบใดที่หน่วยความจำที่ใช้ในการจัดเก็บองค์ประกอบ k ที่พิจารณาไม่เกินขีดจำกัด

• MajorSort
|  fields: [a ASC, b DESC]
|  limit: 10
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 1

Concat

เชื่อมผลลัพธ์ของโหนดย่อยหลายโหนดและแสดงผลลัพธ์ไปยังโหนดระดับบน โหนดนี้จะไม่ขจัดข้อมูลซ้ำที่ปรากฏในโหนดย่อยหลายโหนด และลำดับของผลลัพธ์ที่แสดงผลจะไม่ได้กำหนดไว้

• Concat
├── • Fetch
...
├── • Fetch

Compute

ประเมินชุดนิพจน์ โดยกำหนดผลลัพธ์ให้กับชุดตัวแปร

• Compute
|  $user_1: user
|  $full_name_1: str_concat($first_name_1, " ", $last_name_1)
|  $address_1: UNSET
|  records returned: 1

ตัวกรอง

แสดงผลแถวแบบเลือกเฉพาะในกรณีที่แถวตรงกับนิพจน์ที่ระบุ

• Filter
|  expression: $eq(foo, "bar")
|  records returned: 1

RecordCount

นับจำนวนแถวที่โหนดย่อยสร้างขึ้นและแสดงผลจำนวนปัจจุบันไปยังตัวแปรที่ระบุในแอตทริบิวต์ count

• RecordCount
|  count: $row_number_1
|  records returned: 1

ค่า

สร้างลำดับค่าตามตัวอักษรเพื่อใช้ ใช้เป็นหลักเมื่อมีการระบุรายการเอกสารเป็นอินพุตของการค้นหา

• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]

Unnest

ยกเลิกการซ้อนค่าที่โหนดย่อยสร้างขึ้น

• Unnest
|  expression: foo AS unnested_foo

ขีดจำกัด

จำกัดจำนวนแถวที่แสดงผลไปยังโหนดระดับบน

• Limit
|  limit: 10
|  records returned: 1

หักลบ

ข้ามแถวจำนวนที่กำหนดซึ่งโหนดย่อยสร้างขึ้น

• Offset
|  offset: 10
|  records returned: 1