Медленный запрос n1ql с использованием объекта структуры объектов

В нашей базе couchbase db есть ведро с относительно большими объектами. Внутри этих объектов есть другие объекты, скажем, люди. Это должен быть массив, однако по какой-то причине нам пришлось создать его как объект объектов, и вот как он выглядит:

{
    "companyName": "company name",
    "companyid": "11111-GUID-11111",
    "people": {
        "22222-GUID-22222": {
            "peopleid": "22222-GUID-22222",
            "name": "name1"
        },
        "33333-GUID-33333": {
            "peopleid": "33333-GUID-33333",
            "name": "name2"
        },
        "44444-GUID-44444": {
            "peopleid": "44444-GUID-44444",
            "name": "name3"
        }
    }
}

У него также есть подобъекты с похожей структурой.

Я могу делать запросы к этому документу следующим образом:

SELECT c.*
FROM companies c
WHERE ANY v IN OBJECT_VALUES(c.people) SATISFIES v.peopleid = "22222-GUID-22222" END 
LIMIT 100 
OFFSET 40000;

У меня есть ведро, в котором есть 50000 таких документов.

Вышеупомянутый запрос выполняется отлично и дает мне правильный ответ, но мне нужно ждать ответа около 25 секунд.

Есть ли возможность создать правильные индексы для этой структуры? Или любое решение, которое могло бы ускорить запрос?


person sz tech    schedule 12.10.2017    source источник


Ответы (1)


Вы можете попробовать создать индекс массива, как описано https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-language-reference/indexing-arrays.html. Вы упомянули, что большие объекты проверяют ограничение размера ключа индекса массива.

СОЗДАТЬ индекс ia1 по компаниям (РАЗЛИЧНЫЙ Массив v.peopleid ДЛЯ v IN OBJECT_VALUES (люди) END);

При использовании большого смещения вы теряете много документов. Если вы используете 4.6.2+ (потому что он может использовать неявный индекс покрытого массива, описанный в приведенной выше ссылке), вы можете получить META (). Id документов LIMIT с помощью покрытого запроса и получить необходимые документы, как показано ниже.

SELECT c.* FROM
    (SELECT RAW META(c).id FROM companies c
       WHERE ANY v IN OBJECT_VALUES(c.people) 
                  SATISFIES v.peopleid = "22222-GUID-22222" END 
       LIMIT 100 OFFSET 40000) AS q 
 JOIN companies c ON KEYS q ;
person vsr    schedule 12.10.2017
comment
вы самые лучшие. Работает как часы. Вместо 25 секунд я получаю ответы через 2,5 секунды. - person sz tech; 12.10.2017
comment
Если запрос становится более сложным и у объектов людей есть, скажем, домашние животные с похожей структурой (имя и петид). Есть ли возможность создать указатель для петида? - person sz tech; 13.10.2017
comment
Вы можете создать другой индекс и запрос для этого CREATE index ia2 ON компаний (DISTINCT ARRAY v.petid FOR v IN OBJECT_VALUES (pets) END); - person vsr; 13.10.2017
comment
Я пробовал этот новый индекс, но запрос все еще выполняется медленно. Обратите внимание, что объект pets находится внутри объекта people, например: "people": { "22222-GUID-22222": { "peopleid": "22222-GUID-22222", "name": "name1", "pets": {"33333-GUID-33333-pet": { "petid": "33333-GUID-33333-pet", "name": "petname" }} } Когда я пытаюсь сделать запрос, где я также хочу запросить по petid, запрос занимает около 40 секунд (со смещением 40k). Обратите внимание, что настоящая база данных намного серьезнее, я использую только людей и домашних животных, потому что она конфиденциальна. - person sz tech; 16.10.2017
comment
Пожалуйста, ознакомьтесь с Примером 4: Индексирование отдельных элементов вложенных массивов (C4, Q4), поскольку OBJECT_VALUES () создает массив и следуйте аналогичным правилам developer.couchbase.com/documentation/server/current/n1ql/. - person vsr; 16.10.2017
comment
Спасибо @vsr, очень хорошо работает. Единственная проблема заключается в том, что я хочу выполнить запрос по «petid» и «peopleid» в одном и том же запросе. Потом снова замедляется. - person sz tech; 17.10.2017
comment
Вы пробовали два предложения ANY: одно для peopleid и другое petid с обоими индексами - person vsr; 17.10.2017
comment
Да, но я только что понял, что на самом деле проблема в другой части запроса. Я также прикрепил идентификатор компании, и это была самая медленная часть. Даже если бы я создал индекс и для этого, например: CREATE INDEX ia3 ON _2 _ (_ 3_). И использовал для этого оператор! =, Потому что я думал, что использование этого оператора (в сочетании с И) должно ускорить запрос. - person sz tech; 17.10.2017
comment
Мой запрос выглядит так: SELECT c.* FROM (SELECT RAW META(c).id FROM companies c WHERE ANY v IN OBJECT_VALUES(c.people) SATISFIES ANY pet in OBJECT_VALUES(v.pets) SATISFIES pet.petid = "1111111-111111-pet" END AND v.peopleid = "1111111-111111-people" END AND c.companyid != "000045001-company" LIMIT 30 OFFSET 40000) AS q JOIN companies r ON KEYS q;. Бег занимает 40 секунд. Без идентификатора компании это занимает около 4 секунд. - person sz tech; 17.10.2017
comment
для companyid вы можете создать составной индекс, например CREATE index ia1 ON Companies (DISTINCT ARRAY v.peopleid FOR v IN OBJECT_VALUES (people) END, companyid); и опустите ia3. Это сложно, потому что у вас есть два условия для УДОВЛЕТВОРЕНИЯ, и индекс не будет охватывать пользователя (индекс не имеет обеих данных). Лучший способ - просто сохранить ia1 и SELECT c. * FROM companies c WHERE ANY v IN OBJECT_VALUES (c.people ) УДОВЛЕТВОРИТ ЛЮБОГО питомца в OBJECT_VALUES (v.pets) УДОВЛЕТВОРЕННО pet.petid = 1111111-111111-pet END AND v.peopleid = 1111111-111111-people END И c.companyid! = 000045001-company LIMIT 30 OFFSET 40000; - person vsr; 17.10.2017
comment
Также попробуйте это. СОЗДАТЬ индекс ia4 для компаний (DISTINCT ARRAY (DISTINCT ARRAY [v.peopleid, p.petid] FOR p IN OBJECT_VALUES (v.pets) END) FOR v IN OBJECT_VALUES (people) END, companyid); ВЫБРАТЬ c. * FROM (ВЫБРАТЬ RAW META (c) .id ОТ компаний c WHERE ANY v IN OBJECT_VALUES (c.people) УДОВЛЕТВОРИТ ЛЮБОЙ p в OBJECT_VALUES (v.pets) SATISFIES [v.peopleid, p.petid] = [1111111 -111111-people, 1111111-111111-pet] КОНЕЦ КОНЕЦ И c.companyid! = 000045001-company LIMIT 30 OFFSET 40000) КАК q ПРИСОЕДИНЯЙТЕСЬ к компаниям r НА КЛЮЧАХ q; - person vsr; 17.10.2017
comment
Давайте продолжим это обсуждение в чате. - person sz tech; 18.10.2017