を照会します。大きな違いは次のコレクションに基づいて
data_invoices (document, 100,000 total records, 2 tenants)
hash: tenantId
persistent: createdOn
data_jobs (document, 10,000 total records, 2 tenants)
hash: tenantId
persistent: createdOn
data_links (edge, 100,000 total records)
persistent: createdOn
persistent (sparse): replacedOn
リンク集は、ランダムなジョブに1枚の請求書を接続するので、ジョブは、ゼロ以上の請求書を持っていることがあります。請求書には1つ以上のジョブが必要ですが、私のデータでは、各請求書は1つのジョブにのみ対応しています。 date
フィルタは、すべてのデータがxxx
またはyyy
のいずれかであるため、フィルタに実際にデータをフィルタ処理することはなく(指定された日付の値よりも小さい)、tenantId
フィルタもフィルタしません。
data_jobsとdata_invoicesの一般的な構造は次のとおりです。
tenantId: string;
createdOn: number;
data: [{
createdOn: number;
values: {
...collection specific data here...
};
}];
data_invoices
の収集特定のデータ構造は次のとおりです。
number: number;
amount: number;
data_jobs
の収集具体的なデータ構造は次のとおりです。
name: string;
data_の構造_リンクテーブルには、次のとおりです。
createdOn: number;
replacedOn?: number; // though I don't have any records with this value set
createdOn
フィールドは、1970年からダニ、そして今日まで2000年1月1日からのランダムな日付であるとして表される日付値です。
amount
フィールドは、10〜10,000の任意の通貨値(小数点以下2桁)です。
number
フィールドは、自動番号型フィールドです。
2つの非常によく似た質問がありますが、1つの方法(請求書へのジョブ)は非常に早く、もう1つは時間がかかります。
このクエリは1.85秒かかります:
LET date = 1495616898128
FOR job IN data_jobs
FILTER job.tenantId IN ['xxx', 'yyy']
FILTER job.createdOn<=date
LET jobData = (job.data[* FILTER CURRENT.createdOn<=date LIMIT 1])[0]
FILTER CONTAINS(jobData.values.name, 'a')
LET invoices = (
FOR invoice, link IN 1 INBOUND job data_links
FILTER link.createdOn<=date AND (link.replacedOn == NULL OR
link.replacedOn>date)
LET invoiceData = (invoice.data[* FILTER CURRENT.createdOn<=date LIMIT 1])[0]
FILTER invoiceData.values.amount>1000
COLLECT WITH COUNT INTO count
RETURN {
count
}
)[0]
FILTER invoices.count>0
SORT jobData.values.name ASC
LIMIT 0,8
RETURN job
このクエリは、8.5秒かかります:
LET date = 1495616898128
FOR invoice IN data_invoices
FILTER invoice.tenantId IN ['xxx', 'yyy']
FILTER invoice.createdOn<=date
LET invoiceData = (invoice.data[* FILTER CURRENT.createdOn<=date LIMIT 1])[0]
FILTER invoiceData.values.amount>1000
LET jobs = (
FOR job, link IN 1 OUTBOUND invoice data_links
FILTER link.createdOn<=date AND (link.replacedOn == NULL
OR link.replacedOn>date)
LET jobData = (job.data[* FILTER CURRENT.createdOn<=date LIMIT 1])[0]
FILTER CONTAINS(jobData.values.name, 'a')
COLLECT WITH COUNT INTO count
RETURN {
count
}
)[0]
FILTER jobs.count>0
SORT invoiceData.values.amount ASC
LIMIT 0,8
RETURN invoice
「私は両方のクエリが異なるデータを提供していることを認識しますが、処理時間は同じshouldnする必要がありますそれ?両方とも、リンクテーブルを介して両方のテーブルをフィルタリングしており、両方とも他方のテーブルで集約を実行しています。なぜ片方向が他の方法よりもずっと速いのか分かりません。これらのクエリのパフォーマンスを向上させるためにできることはありますか?
'data_jobs'には、同時に2つの属性、つまりtenantIdと' createdOn'のフィルタ条件があります。両方に永続インデックスを作成した場合のクエリのパフォーマンスは、 'tenantId、createdOn'と定義してください。複数の属性インデックスは、特に同じクエリで両方を使用している場合に特に役立ちます。 –
@DavidThomasありがとうございました。しかし、私が言ったように、それらのフィルタは実際にレコードを取ることはありません(故意に - 私は最悪のシナリオテストです)。単一のインデックス、私はそれが多くなることを疑う - 私は間違いなくそれを行っても間に合うでしょう。 – Anupheaus
あなたが見つけたものにコメントを投稿してください。微調整をすると、私は124秒間で0.2秒かかったクエリを1つ持っていました。私にとって重要なのは、マルチカラムインデックスであり、クエリを作成して、AQLエンジンがどのインデックスを使用するのかを簡単に判断できるようにすることでした。 –