Создание индекса Couchbase для нескольких комбинаций критериев фильтрации в запросе N1QL

У нас есть два типа документов, CS и //, когда все дополнительные фильтры присутствуют в одном сегменте, и мы объединяем два типа с помощью поля latestCommandStatusId в PCI < / strong>, который является идентификатором документа CS, а также несколькими необязательными и некоторыми обязательными полями в N1QL. Время отклика на производственном сервере слишком велико, более 5-6 секунд, нам нужно уменьшить его до менее 300 миллисекунд.

У нас есть два типа документов, CS и PCI в одной корзине, и мы объединяем эти два, используя поле latestCommandStatusId PCI, которое является идентификатором документа CS и несколькими необязательными и некоторыми обязательными полями в N1QL.

CS(id = request10)
{
  "id": "request10",
  "_class": "CS",
  "status": "FAILED"
}


PCI(id = pci1)
{
  "id": "pci1",
  "latestCommandStatusId": "request10",  // equal to some CS doc id
  "_class": "PCI",
  "createdDateTime": 1672531200000,
  "effectiveDateTime": 1688083200000,
  "locationDSL": {
    "parameters": {
      "locationClusterId": ["L3", "L1","L2"]
    }
  },
  "productDSL": {
    "parameters": {
      "tpnb": ["02","04"]
    }
  }
}

Теперь, чтобы присоединиться к этим документам, у нас есть следующий запрос, который работает нормально, но занимает слишком много времени на производственном сервере с огромным набором данных. Мой вопрос, какие индексы нам нужно создать, чтобы сократить время отклика для указанной ниже комбинации фильтров.

SELECT  META(pci).id AS _ID,META(pci).cas AS _CAS, pci,cs
FROM prices pci JOIN prices cs ON KEYS pci.latestCommandStatusId   // join CS and PCI on pci.latestCommandStatusId which is id of CS doc
WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND 'some_tpnb' IN pci.productDSL.parameters.tpnb   // optional filter if some_tpnb is null in request param
AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId   // optional filter if some_locationClusterId is null in request param
AND  pci.state = "some_pci_state"  // optional filter if some_pci_state is null in request param
AND cs.status = "some_cs_status"   // optional filter if some_cs_status is null in request param
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime DESCending order
OFFSET 0 LIMIT 15   // mandatory pagination

поэтому у нас есть несколько обязательных фильтров и несколько дополнительных фильтров в зависимости от ввода

например, если все дополнительные фильтры равны нулю

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime 
OFFSET 0 LIMIT 15   // mandatory pagination

например, если some_tpnb не равен нулю в параметре запроса, а другие дополнительные фильтры равны нулю

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND 'some_tpnb' IN pci.productDSL.parameters.tpnb   // if some_tpnb is not null in request param and other optional filters are null
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime 
OFFSET 0 LIMIT 15   // mandatory pagination

например: если some_locationClusterId не равен нулю, а другие дополнительные фильтры равны нулю

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId   
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime 
OFFSET 0 LIMIT 15   // mandatory pagination

например: если some_pci_state и some_cs_status не равны нулю, а другие дополнительные фильтры равны нулю

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND  pci.state = "some_pci_state"   
AND cs.status = "some_cs_status"   
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime DESCending order
OFFSET 0 LIMIT 15   // mandatory pagination

например: когда присутствуют все дополнительные фильтры

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   
AND 'some_tpnb' IN pci.productDSL.parameters.tpnb   
AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId   
AND  pci.state = "some_pci_state"  
AND cs.status = "some_cs_status"   
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime  
OFFSET 0 LIMIT 15   // mandatory pagination

person Momin Fakhruddin    schedule 11.06.2019    source источник


Ответы (1)


попробуйте это и посмотрите, поможет ли это

SELECT  META(pci).id AS _ID,META(pci).cas AS _CAS, pci,cs
FROM prices pci
JOIN prices cs ON KEYS pci.latestCommandStatusId
WHERE pci._class = "PCI"
      AND cs._class = "CS"
      AND pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"
      AND 'some_tpnb' IN pci.productDSL.parameters.tpnb
      AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId
      AND  pci.state = "some_pci_state"
      AND  cs.status = "some_cs_status"
ORDER BY pci.effectiveDateTime DESC
OFFSET 0 LIMIT 15

CREATE INDEX ix1 ON prices(effectiveDateTime DESC,state) WHERE _class = "PCI";
person vsr    schedule 11.06.2019
comment
проверим его и сообщим ... но разве нам не нужны несколько индексов в зависимости от того, есть ли у нас дополнительные фильтры в запросе? ... можем ли мы покрыть весь запрос одним индексом покрытия? - person Momin Fakhruddin; 14.06.2019