1

このクエリが十分にクエリ最適化されていない可能性はありますか?誰かがそれを改善するためのヒントを持っている可能性がありますか? 現在、私がそれを殺すまで数時間続きます。

図:

  • 小さいレコードが 200 万未満のコレクション (2 GB の RAM が必要)
  • 16 個のインデックスを持つ (1.2 GB の RAM が必要)

arangosh [SES]> db.AuditSearch.figures()

{
  "alive" : {
    "count" : 1940004,
    "size" : 2052009624
  },
  "dead" : {
    "count" : 397017,
"size" : 431456792,
"deletion" : 52950
  },
  "datafiles" : {
    "count" : 20,
    "fileSize" : 2132549880
  },
  "journals" : {
    "count" : 1,
    "fileSize" : 67108864
  },
  "compactors" : {
    "count" : 1,
    "fileSize" : 256528080
  },
  "shapefiles" : {
    "count" : 0,
    "fileSize" : 0
  },
  "shapes" : {
    "count" : 1004,
    "size" : 1310704
  },
  "attributes" : {
    "count" : 65,
    "size" : 3408
  },
  "indexes" : {
    "count" : 16,
    "size" : 1198718256
  },
  "lastTick" : "14686717826252",
  "uncollectedLogfileEntries" : 0
}

クエリ:

FOR a IN AuditsSearch

  // split the task as it currently is not possible to execute at once:
  FILTER IS_NULL(a.analytics)
  LIMIT 200000, 200000
  // end of split ... which also does not work

    LET utcTimestamp = DATE_TIMESTAMP(a.timestamp)
    LET intNumResults = TO_NUMBER(a.resultcount)
    LET intDuration = TO_NUMBER(a.duration)
    LET url = SPLIT(a.docid, "|")[1]

UPDATE a WITH { "analytics": { "utcTimestamp": utcTimestamp, "duration": intDuration, "numResults": intNumResults, "url": url } } IN AuditsSearch

索引:

[
{"id":"AuditsSearch/0","type":"primary","unique":true,"fields":["_key"]},
{"id":"AuditsSearch/13943073289094","type":"hash","unique":false,"fields":["eventtype"]},
{"id":"AuditsSearch/13943144067974","type":"hash","unique":false,"fields":["profile"]},
{"id":"AuditsSearch/13943163138950","type":"hash","unique":false,"fields":["sessionid"]},
{"id":"AuditsSearch/13943169299334","type":"hash","unique":false,"fields":["resultid"]},
{"id":"AuditsSearch/13943195644806","type":"skiplist","unique":false,"fields":["duration"]},
{"id":"AuditsSearch/13947101328262","type":"skiplist","unique":false,"fields":["timestamp"]},
{"id":"AuditsSearch/14023678636934","type":"skiplist","unique":false,"fields":["analytics.utcTimestamp"]},
{"id":"AuditsSearch/14064254132425","type":"skiplist","unique":false,"fields":["resultcount"]},
{"id":"AuditsSearch/14101960466633","type":"skiplist","unique":false,"fields":["analytics.duration"]},
{"id":"AuditsSearch/14101968134345","type":"skiplist","unique":false,"fields":["analytics.numResults"]},
{"id":"AuditsSearch/14140104909001","type":"hash","unique":false,"fields":["analytics.url"]},
{"id":"AuditsSearch/14168504672457","type":"skiplist","unique":false,"fields":["sessionid"]},
{"id":"AuditsSearch/14168754823369","type":"skiplist","unique":false,"fields":["eventtype"]},
{"id":"AuditsSearch/14169726263497","type":"hash","unique":false,"fields":["isadmin"]},
{"id":"AuditsSearch/14169732554953","type":"hash","unique":false,"fields":["isdelegatedadmin"]}
]

実行計画:

{
  "plan": {
    "nodes": [{
      "type": "SingletonNode",
      "dependencies": [],
      "id": 1,
      "estimatedCost": 1,
      "estimatedNrItems": 1
    },
    {
      "type": "EnumerateCollectionNode",
      "dependencies": [1],
      "id": 2,
      "estimatedCost": 1704564,
      "estimatedNrItems": 1704563,
      "database": "SES",
      "collection": "AuditsSearch",
      "outVariable": {
        "id": 0,
        "name": "a"
      },
      "random": false
    },
    {
      "type": "CalculationNode",
      "dependencies": [2],
      "id": 3,
      "estimatedCost": 3409127,
      "estimatedNrItems": 1704563,
      "expression": {
        "type": "function call",
        "name": "IS_NULL",
        "subNodes": [{
          "type": "array",
          "subNodes": [{
            "type": "attribute access",
            "name": "analytics",
            "subNodes": [{
              "type": "reference",
              "name": "a",
              "id": 0
            }]
          }]
        }]
      },
      "outVariable": {
        "id": 5,
        "name": "5"
      },
      "canThrow": false
    },
    {
      "type": "FilterNode",
      "dependencies": [3],
      "id": 4,
      "estimatedCost": 5113690,
      "estimatedNrItems": 1704563,
      "inVariable": {
        "id": 5,
        "name": "5"
      }
    },
    {
      "type": "CalculationNode",
      "dependencies": [4],
      "id": 6,
      "estimatedCost": 6818253,
      "estimatedNrItems": 1704563,
      "expression": {
        "type": "function call",
        "name": "DATE_TIMESTAMP",
        "subNodes": [{
          "type": "array",
          "subNodes": [{
            "type": "attribute access",
            "name": "timestamp",
            "subNodes": [{
              "type": "reference",
              "name": "a",
              "id": 0
            }]
          }]
        }]
      },
      "outVariable": {
        "id": 1,
        "name": "utcTimestamp"
      },
      "canThrow": false
    },
    {
      "type": "CalculationNode",
      "dependencies": [6],
      "id": 7,
      "estimatedCost": 8522816,
      "estimatedNrItems": 1704563,
      "expression": {
        "type": "function call",
        "name": "TO_NUMBER",
        "subNodes": [{
          "type": "array",
          "subNodes": [{
            "type": "attribute access",
            "name": "resultcount",
            "subNodes": [{
              "type": "reference",
              "name": "a",
              "id": 0
            }]
          }]
        }]
      },
      "outVariable": {
        "id": 2,
        "name": "intNumResults"
      },
      "canThrow": false
    },
    {
      "type": "CalculationNode",
      "dependencies": [7],
      "id": 8,
      "estimatedCost": 10227379,
      "estimatedNrItems": 1704563,
      "expression": {
        "type": "function call",
        "name": "TO_NUMBER",
        "subNodes": [{
          "type": "array",
          "subNodes": [{
            "type": "attribute access",
            "name": "duration",
            "subNodes": [{
              "type": "reference",
              "name": "a",
              "id": 0
            }]
          }]
        }]
      },
      "outVariable": {
        "id": 3,
        "name": "intDuration"
      },
      "canThrow": false
    },
    {
      "type": "CalculationNode",
      "dependencies": [8],
      "id": 9,
      "estimatedCost": 11931942,
      "estimatedNrItems": 1704563,
      "expression": {
        "type": "indexed access",
        "subNodes": [{
          "type": "function call",
          "name": "SPLIT",
          "subNodes": [{
            "type": "array",
            "subNodes": [{
              "type": "attribute access",
              "name": "docid",
              "subNodes": [{
                "type": "reference",
                "name": "a",
                "id": 0
              }]
            },
            {
              "type": "value",
              "value": "|"
            }]
          }]
        },
        {
          "type": "value",
          "value": 1
        }]
      },
      "outVariable": {
        "id": 4,
        "name": "url"
      },
      "canThrow": false
    },
    {
      "type": "CalculationNode",
      "dependencies": [9],
      "id": 10,
      "estimatedCost": 13636505,
      "estimatedNrItems": 1704563,
      "expression": {
        "type": "object",
        "subNodes": [{
          "type": "object element",
          "name": "analytics",
          "subNodes": [{
            "type": "object",
            "subNodes": [{
              "type": "object element",
              "name": "utcTimestamp",
              "subNodes": [{
                "type": "reference",
                "name": "utcTimestamp",
                "id": 1
              }]
            },
            {
              "type": "object element",
              "name": "duration",
              "subNodes": [{
                "type": "reference",
                "name": "intDuration",
                "id": 3
              }]
            },
            {
              "type": "object element",
              "name": "numResults",
              "subNodes": [{
                "type": "reference",
                "name": "intNumResults",
                "id": 2
              }]
            },
            {
              "type": "object element",
              "name": "url",
              "subNodes": [{
                "type": "reference",
                "name": "url",
                "id": 4
              }]
            }]
          }]
        }]
      },
      "outVariable": {
        "id": 6,
        "name": "6"
      },
      "canThrow": false
    },
    {
      "type": "LimitNode",
      "dependencies": [10],
      "id": 5,
      "estimatedCost": 13836505,
      "estimatedNrItems": 200000,
      "offset": 0,
      "limit": 200000,
      "fullCount": false
    },
    {
      "type": "UpdateNode",
      "dependencies": [5],
      "id": 11,
      "estimatedCost": 14036505,
      "estimatedNrItems": 0,
      "inDocVariable": {
        "id": 6,
        "name": "6"
      },
      "database": "SES",
      "collection": "AuditsSearch",
      "modificationFlags": {
        "ignoreErrors": false,
        "waitForSync": false,
        "nullMeansRemove": false,
        "mergeObjects": true,
        "ignoreDocumentNotFound": false
      },
      "inKeyVariable": {
        "id": 0,
        "name": "a"
      }
    }],
    "rules": ["move-calculations-up",
    "move-filters-up",
    "move-calculations-up-2",
    "move-filters-up-2"],
    "collections": [{
      "name": "AuditsSearch",
      "type": "write"
    }],
    "variables": [{
      "id": 0,
      "name": "a"
    },
    {
      "id": 1,
      "name": "utcTimestamp"
    },
    {
      "id": 4,
      "name": "url"
    },
    {
      "id": 2,
      "name": "intNumResults"
    },
    {
      "id": 3,
      "name": "intDuration"
    },
    {
      "id": 6,
      "name": "6"
    },
    {
      "id": 5,
      "name": "5"
    }],
    "estimatedCost": 14036505,
    "estimatedNrItems": 0
  },
  "warnings": [],
  "stats": {
    "rulesExecuted": 19,
    "rulesSkipped": 0,
    "plansCreated": 1
  }
}
4

1 に答える 1

1

上記の議論から得られる重要なポイントを要約すると、次のようになります。

最近db._explain(<your aql query goes here>)では、生の実行計画を取得する代わりに使用する必要があります。経験豊富な動作の一部は、新しい arangodb バージョンで改善されています。

  • オプティマイザーは、その決定において常に完璧であるとは限りませんが、改善しています。フィルターの前の経験豊富な LET プルは、オプティマイザーによって検出され、回避されるようになりました。そのため、ArangoDB チームは常にクエリについて学習することに熱心です。
  • 複雑なクエリのどの部分がリソースの使用率が高いかを知りたい場合は、それを分割して時間を測定するビットを試すと役立つ場合があります。
  • 一時的な揮発性コレクションを使用することが理にかなっている場合があります。
  • インデックスの維持にはコストがかかります。大量のドキュメントを移動する予定がある場合は、インデックスを削除して後で再作成することをお勧めします。
  • 一意でないハッシュ インデックスは、選択性が低下した場合、多くのパフォーマンスが必要になる場合があります。つまり、多数のハッシュ衝突または重複キーがある場合、インデックスの使用コストが挿入時とクエリ時の両方で上昇します。
  • 一意でないハッシュ インデックスには、挿入の場合に O(1) の償却コストがあります (したがって、インデックスの作成は依然として高速です) が、更新/削除の場合は、同一のキーを持つ要素の中から「正しい」要素を見つける必要があります。同じキーを持つインデックス エントリが多数ある場合、「正しい」アイテムを見つけるには最大n回の比較が必要です (n は同じキーを持つアイテムの数です)。もちろん、一意のハッシュ インデックスにはこの問題はありませんが、同一のキーが多数ある一意でないインデックスでは問題が発生します。
  • 多くのインデックスを持つことは、前述のインデックス メンテナンスのオーバーヘッドを合計します。
  • truncate()インデックスのメンテナンスが含まれます。インデックスを削除して再作成することをお勧めします。
于 2016-03-31T14:27:31.007 に答える