Couchbase查询的索引

时间:2019-01-07 10:53:39

标签: couchbase n1ql spring-data-couchbase

能否请您为此查询建议可能的沙发床索引以及如何选择?

SELECT Count(*) AS count 
FROM   `ORDER` 
WHERE  `_class` = "com.lbk.entities.OrderEntity" 
AND    ( 
              lower(buyer.contact.firstname) LIKE '%aziz%' 
       OR     lower(buyer.contact.lastname) LIKE '%aziz%' 
       OR     ANY communicationchannel IN buyer.contact.communicationchannel satisfies ( communicationchannel.communicationchannelcode = 'EMAIL'
       AND    communicationchannel.communicationvalue = NULL ) 
END ) 
AND    ordertypecode = '220' 
AND    ( 
              ordercategory != 'EXCLUDED_CAT' 
       OR     ordercategory IS NOT valued ) 
AND    creationdatetime IN 
       ( 
                SELECT   raw max(o2.creationdatetime) 
                FROM     `ORDER` o2 
                WHERE    ( 
                                  lower(o2.buyer.contact.firstname) LIKE '%aziz%' 
                         OR       lower(o2.buyer.contact.lastname) LIKE '%aziz%' 
                         OR       ANY communicationchannel IN o2.buyer.contact.communicationchannel satisfies ( communicationchannel.communicationchannelcode = 'EMAIL'
                         AND      communicationchannel.communicationvalue = NULL ) 
                END ) 
                AND      ANY communicationchannel IN o2.buyer.contact.communicationchannel satisfies ( communicationchannel.communicationchannelcode = 'EMAIL'
                AND      communicationchannel.communicationvalue IS NOT NULL )  END 
                AND      o2.ordertypecode = '220' 
                AND      ( 
                                  o2.ordercategory != 'EXCLUDED_CAT' 
                         OR       o2.ordercategory IS NOT valued) 
                GROUP BY ( array item.communicationvalue FOR item IN o2.buyer.contact.communicationchannel WHEN item.communicationchannelcode = 'EMAIL'
                END )
            )

我已经创建了该索引,该索引已被查询击中:

CREATE INDEX `idx_customer` ON 
`order`(`_class`, ((`buyer`.`contact`).`firstname`), ((`buyer`.`contact`).`lastname`), (DISTINCT (array
(`aoc`.`communicationvalue`) FOR `aoc` IN ((`buyer`.`contact`).`communicationchannel`) WHEN 
((`aoc`.`communicationchannelcode`) = "EMAIL") end))) 

但是我的表现很差,并且与其他响应相对应,这主要是因为我的索引设计不佳。

我的查询的解释是:

{
  "plan": {
    "#operator": "Sequence",
    "~children": [
      {
        "#operator": "UnionScan",
        "scans": [
          {
            "#operator": "IntersectScan",
            "scans": [
              {
                "#operator": "IndexScan3",
                "index": "idx_customer1",
                "index_id": "d1463e49b12fcd45",
                "index_projection": {
                  "primary_key": true
                },
                "keyspace": "order",
                "namespace": "default",
                "spans": [
                  {
                    "range": [
                      {
                        "high": "\"220\"",
                        "inclusion": 3,
                        "low": "\"220\""
                      },
                      {
                        "inclusion": 0,
                        "low": "null"
                      }
                    ]
                  }
                ],
                "using": "gsi"
              },
              {
                "#operator": "DistinctScan",
                "scan": {
                  "#operator": "IndexScan3",
                  "index": "idx_customer",
                  "index_id": "2132a2f8632e76f3",
                  "index_projection": {
                    "primary_key": true
                  },
                  "keyspace": "order",
                  "namespace": "default",
                  "spans": [
                    {
                      "range": [
                        {
                          "high": "\"com.lbk.entities.OrderEntity\"",
                          "inclusion": 3,
                          "low": "\"com.lbk.entities.OrderEntity\""
                        },
                        {
                          "inclusion": 0,
                          "low": "null"
                        }
                      ]
                    }
                  ],
                  "using": "gsi"
                }
              }
            ]
          },
          {
            "#operator": "IndexScan3",
            "index": "idx_customer1",
            "index_id": "d1463e49b12fcd45",
            "index_projection": {
              "primary_key": true
            },
            "keyspace": "order",
            "namespace": "default",
            "spans": [
              {
                "range": [
                  {
                    "high": "\"220\"",
                    "inclusion": 3,
                    "low": "\"220\""
                  },
                  {
                    "inclusion": 0,
                    "low": "null"
                  }
                ]
              }
            ],
            "using": "gsi"
          }
        ]
      },
      {
        "#operator": "Fetch",
        "keyspace": "order",
        "namespace": "default"
      },
      {
        "#operator": "Parallel",
        "~child": {
          "#operator": "Sequence",
          "~children": [
            {
              "#operator": "Filter",
              "condition": "((((((`order`.`_class`) = \"com.lbk.entities.OrderEntity\") and (((lower((((`order`.`buyer`).`contact`).`firstName`)) like \"%aziz%\") or (lower((((`order`.`buyer`).`contact`).`lastName`)) like \"%aziz%\")) or any `communicationChannel` in (((`order`.`buyer`).`contact`).`communicationChannel`) satisfies (((`communicationChannel`.`communicationChannelCode`) = \"EMAIL\") and ((`communicationChannel`.`communicationValue`) = null)) end)) and ((`order`.`orderTypeCode`) = \"220\")) and ((not ((`order`.`orderCategory`) = \"EXCLUDED_CAT\")) or ((`order`.`orderCategory`) is not valued))) and ((`order`.`creationDateTime`) in (select raw max((`O2`.`creationDateTime`)) from `order` as `O2` where ((((((lower((((`O2`.`buyer`).`contact`).`firstName`)) like \"%aziz%\") or (lower((((`O2`.`buyer`).`contact`).`lastName`)) like \"%aziz%\")) or any `communicationChannel` in (((`O2`.`buyer`).`contact`).`communicationChannel`) satisfies (((`communicationChannel`.`communicationChannelCode`) = \"EMAIL\") and ((`communicationChannel`.`communicationValue`) = null)) end) and any `communicationChannel` in (((`O2`.`buyer`).`contact`).`communicationChannel`) satisfies (((`communicationChannel`.`communicationChannelCode`) = \"EMAIL\") and ((`communicationChannel`.`communicationValue`) is not null)) end) and ((`O2`.`orderTypeCode`) = \"220\")) and ((not ((`O2`.`orderCategory`) = \"EXCLUDED_CAT\")) or ((`O2`.`orderCategory`) is not valued)))  group by array (`item`.`communicationValue`) for `item` in (((`O2`.`buyer`).`contact`).`communicationChannel`) when ((`item`.`communicationChannelCode`) = \"EMAIL\") end)))"
            },
            {
              "#operator": "InitialGroup",
              "aggregates": [
                "count(*)"
              ],
              "group_keys": []
            }
          ]
        }
      },
      {
        "#operator": "IntermediateGroup",
        "aggregates": [
          "count(*)"
        ],
        "group_keys": []
      },
      {
        "#operator": "FinalGroup",
        "aggregates": [
          "count(*)"
        ],
        "group_keys": []
      },
      {
        "#operator": "Parallel",
        "~child": {
          "#operator": "Sequence",
          "~children": [
            {
              "#operator": "InitialProject",
              "result_terms": [
                {
                  "as": "count",
                  "expr": "count(*)"
                }
              ]
            },
            {
              "#operator": "FinalProject"
            }
          ]
        }
      }
    ]
  },
  "text": "SELECT COUNT(*) AS count FROM `order` \nWHERE `_class` = \"com.lbk.entities.OrderEntity\" \nAND ( \nLOWER(buyer.contact.firstName) LIKE '%aziz%' OR LOWER(buyer.contact.lastName) LIKE '%aziz%' \nOR ANY communicationChannel IN buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue  = null ) END )  \nAND orderTypeCode = '220' \nAND (orderCategory != 'EXCLUDED_CAT' OR orderCategory is not valued ) \nAND creationDateTime in (select RAW max(O2.creationDateTime) \nfrom `order` O2 WHERE ( LOWER(O2.buyer.contact.firstName) \nLIKE '%aziz%' OR LOWER(O2.buyer.contact.lastName) LIKE '%aziz%' \nOR ANY communicationChannel IN O2.buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue  = null ) END )  \nAND ANY communicationChannel IN O2.buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue is not null ) END \nAND O2.orderTypeCode = '220' \nAND (O2.orderCategory != 'EXCLUDED_CAT'\nOR O2.orderCategory is not valued) \ngroup by ( ARRAY item.communicationValue FOR item IN O2.buyer.contact.communicationChannel WHEN item.communicationChannelCode = 'EMAIL' END ))"
}

在查询监视器中执行此查询时,它花费了( 2秒,即使我的文档数量很少〜2000):

已过:1.93秒|执行时间:11.93秒|数:1 |大小:34

从spring引导应用程序中使用spring数据执行时,需要花费两倍的时间(4秒)

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

在我看来,您正在两次扫描ORDER。确保是否仅使用ix1进行查询。如果未指定USE INDEX

CREATE INDEX ix1 ON (ordertypecode, buyer.contact.firstname, buyer.contact.lastname, creationdatetime, ordercategory,buyer.contact.communicationchannel)
WHERE `_class` = "com.lbk.entities.OrderEntity";

SELECT SUM(o.cnt) AS count
FROM ( SELECT MAX([o1.creationdatetime,o1.cnt])[1] AS cnt
       FROM (SELECT   acomval, o2.creationdatetime, COUNT(1) AS cnt
             FROM  `ORDER` o2
             LET acomval = (ARRAY ch.communicationvalue FOR ch IN o2.buyer.contact.communicationchannel
                            WHEN ch.communicationchannelcode = 'EMAIL' END )
             WHERE (LOWER(o2.buyer.contact.firstname) LIKE '%aziz%'
                       OR LOWER(o2.buyer.contact.lastname) LIKE '%aziz%'
                       OR ANY ch IN o2.buyer.contact.communicationchannel
                              SATISFIES ( ch.communicationchannelcode = 'EMAIL' AND ch.communicationvalue IS NULL)
                          END
                      )
                      AND ANY ch IN o2.buyer.contact.communicationchannel
                              SATISFIES (ch.communicationchannelcode = 'EMAIL' AND ch.communicationvalue IS NOT NULL)  END
                      AND  o2.`_class` = "com.lbk.entities.OrderEntity"
                      AND  o2.ordertypecode = '220'
                      AND ( o2.ordercategory != 'EXCLUDED_CAT' OR o2.ordercategory IS NOT VALUED)
             GROUP BY acomval, o2.creationdatetime) AS o1
       GROUP BY o1.acomval) AS o;