Большая разница во времени, необходимом для выполнения графовых запросов
На основании следующих коллекций:
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
Коллекция ссылок соединит один счет-фактуру со случайным заданием, поэтому задание может содержать ноль или более счетов. Счет должен иметь одно или несколько заданий, но в моих данных каждый счет соответствует только одному заданию. date
Фильтр фактически не отфильтровывает никакие данные (все они меньше указанного значения даты), и при этом tenantId
фильтр, так как все данные либо xxx
или же yyy
,
Общая структура 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_links:
createdOn: number;
replacedOn?: number; // though I don't have any records with this value set
createdOn
поле - это значение даты, представленное в виде галочек с 1970 года, и случайная дата с 01 января 2000 года по сегодняшний день.
amount
Поле представляет собой случайное значение валюты (2 десятичных знака) от 10 до 10000.
number
field это поле типа автонумерации
У меня есть два очень похожих (на мой взгляд) запроса: один способ (задания на счета) работает очень и очень быстро, другой - на возраст.
Этот запрос занимает 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
Я понимаю, что оба запроса предоставляют разные данные, но время обработки должно быть одинаковым, не так ли? Они оба фильтруют обе таблицы через таблицу связей и выполняют агрегирование с другой. Я не понимаю, почему один путь намного быстрее, чем другой. Могу ли я что-нибудь сделать, чтобы повысить производительность этих запросов, пожалуйста?
1 ответ
Хорошо, странно, но я наткнулся на очень нелогичное (по крайней мере для меня) решение. Сортировка сначала, затем фильтр...???
Этот запрос теперь занимает 1,4 секунды:
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]
SORT invoiceData.values.amount ASC
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
LIMIT 0,8
RETURN invoice
Несмотря на добавление постоянного индекса на data[*].values.amount
, он все еще не использует его (я даже пытался SORT invoice.data[0].values.amount ASC
и он все еще не использует индекс?)
Кто-нибудь может объяснить это, пожалуйста?