【问题标题】:too large execution time of queries on couchbasecouchbase 上查询的执行时间过长
【发布时间】:2016-05-11 01:56:39
【问题描述】:

我是 couchbase 的新手,我正在使用 N1QL 进行一些查询,但这需要很长时间(9 分钟) 我的数据有 200.000 个文档并且文档具有嵌套类型,文档内部的嵌套类型数量为 6.000.000,分布在 200.000 个文档之间,因此 UNNEST 操作很重要。我的数据样本之一是:

{"p_partkey": 2, "lineorder": [{"customer": [{"c_city": "INDONESIA1"}], "lo_supplycost": 54120, "orderdate": [{"d_weeknuminyear": 19}], "supplier": [{"s_phone": "16-789-973-6601|"}], "commitdate": [{"d_year": 1993}], "lo_tax": 7}, {"customer": [{...

我正在做的一个查询是:

SELECT SUM(l.lo_extendedprice*l.lo_discount*0.01) as revenue
from part p UNNEST p.lineorder l UNNEST l.orderdate o 
where o.d_year=1993 and l.lo_discount between 1 and 3 and l.lo_quantity<25;

数据具有上述字段。 但是执行需要9分钟。 我只用我的电脑来做,所以只有一个节点。 我的电脑有 16GB 的 RAM,集群 RAM cota 是 3.2GB,只有一个 3GB 的存储桶。我的数据总大小为 2.45GB。我使用了这里提到的计算:http://docs.couchbase.com/admin/admin/Concepts/bp-sizingGuidelines.html 来调整我的集群和存储桶的大小。 我做错了什么,或者这次对于这么多的数据是正确的?

现在我创建了如下索引:

CREATE INDEX idx_discount ON part( DISTINCT ARRAY l.lo_discount FOR l IN lineorder END );

CREATE INDEX idx_quantity ON part( DISTINCT ARRAY l.lo_quantity FOR l IN lineorder END );

CREATE INDEX idx_year ON part( DISTINCT ARRAY o.d_year FOR o IN ( DISTINCT ARRAY l.orderdate FOR l IN lineorder END ) END );

但是数据库不使用它。

一个查询示例是:

SELECT SUM(l.lo_extendedprice*l.lo_discount*0.01) as revenue
from part p UNNEST p.lineorder l UNNEST l.orderdate o 
where o.d_year=1993 and l.lo_discount between 1 and 3 and l.lo_quantity<25;

另一个例子,我已经创建了索引:

CREATE INDEX teste3 ON `part` (DISTINCT ARRAY l.lo_quantity FOR l IN lineorder END );

并查询:

select l.lo_quantity from part as p UNNEST p.lineorder l where l.lo_quantity>20 limit 3

因为我已经删除了主索引,所以它没有执行。返回错误: "键空间部分没有主索引。使用 CREATE PRIMARY INDEX 创建一个。",

【问题讨论】:

    标签: nested benchmarking couchbase n1ql


    【解决方案1】:

    看了http://blog.couchbase.com/2016/may/1.making-most-of-your-arrays..-with-covering-array-indexes-and-more上的博文后发现了问题:

    如果你像这样创建索引:

    CREATE INDEX iflight_day 
           ON `travel-sample` ( DISTINCT ARRAY v.flight FOR v IN schedule END );
    

    您必须在查询中使用相同的字母,在本例中为字母“v”。

    SELECT v.day from `travel-sample` as t UNNEST t.schedule v where v.flight="LY104";
    

    最深层次也是如此:

    CREATE INDEX inested ON `travel-sample`
    ( DISTINCT ARRAY (DISTINCT ARRAY y.flight FOR y IN x.special_flights END) FOR x IN schedule END);
    

    在这种情况下,您必须使用“y”和“x”:

    SELECT x.day from `travel-sample` as t UNNEST t.schedule x UNNEST x.special_flights y where y.flight="AI444";
    

    现在一切正常。

    但是当我这样查询时出现了另一个问题:

    SELECT * from `travel-sample` as t UNNEST t.schedule x UNNEST x.special_flights y 
    where x.day=7 and y.flight="AI444";
    

    仅使用如上创建的日期索引。

      CREATE INDEX day 
               ON `travel-sample` ( DISTINCT ARRAY y.day FOR y IN schedule END );
    

    它只使用一个索引,有时是“day”,有时是“inested”。

    【讨论】:

    • UNNEST 和数组索引之间的变量必须匹配。试试这个: SELECT s.day FROM `travel-sample` AS t UNNEST t.schedule AS v WHERE v.flight="LY146";
    • @geraldss,我刚刚安装了企业版的最新版本。我的查询就像您的查询一样,您只需按 v 更改 s,但它不使用索引 iflight_day,仅当我以这种方式查询时:SELECT s.day from (SELECT schedule FROM travel-sample WHERE ANY v IN schedule SATISFIES v.flight= "LY146" END) as t UNNEST t.schedule s where s.flight="LY146";
    • 不知道为什么会这样。请尝试即将推出的 4.5.1。他们都为我工作。
    • 您使用的是标准全局二级索引还是内存优化全局二级索引?我怎样才能获得 4.5.1?
    • 嗨@geraldss,我发现了这个问题。并改变了我上面的答案。但是当我想查询两个数组字段时,会出现另一个问题。
    【解决方案2】:

    您可以将 Couchbase 4.5(即将推出的 GA)与数组索引结合使用。数组索引可以与 UNNEST 一起使用。它允许您索引数组的各个元素,包括嵌套在其他数组中的数组。

    您可以创建以下索引,然后使用 EXPLAIN 确保有一个 IndexScan 使用您的预期索引。

    CREATE INDEX idx_discount ON part( DISTINCT ARRAY l.lo_discount FOR l IN lineorder END );
    
    CREATE INDEX idx_quantity ON part( DISTINCT ARRAY l.lo_quantity FOR l IN lineorder END );
    
    CREATE INDEX idx_year ON part( DISTINCT ARRAY ( DISTINCT ARRAY o.d_year FOR o IN l.orderdate END ) FOR l IN lineorder END );
    

    【讨论】:

    • 嗨@geraldss,我已经在使用4.5了。我不打算使用索引,因为我会针对它做不同的查询。 Colud 你告诉我我是否正确配置了我的沙发底座,如果不使用索引还有另一种方法来获得更好的性能?感谢您的帮助。
    • 嗨@Raphael,即使您有很多查询,您也需要使用索引。 Couchbase 允许您创建许多索引。
    • 嗨@geraldss,我已经创建了你提到的索引,但是嵌套索引不起作用,我可以创建它们,但它们似乎不存在。我只能问使用主索引。我读过一些关于缺失字段的内容。如果我的某些文档没有字段,则不会创建索引?我可以在字段中使用重复的值吗?
    • 您能否将您的确切 CREATE INDEX 语句和查询添加到问题中。
    • 所以@geraldss,我的查询就像我以前伤心过一样。我创建了像你一样悲伤的索引。
    猜你喜欢
    • 1970-01-01
    • 2019-12-28
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多