Performance N1ql计数不同的关联文档

Performance N1ql计数不同的关联文档,performance,join,count,couchbase,n1ql,Performance,Join,Count,Couchbase,N1ql,我有一个单独的存储桶(Couchbase Community edition 6.5),包含以下文档: employee { type: "Employee" } X { type: "X", employeeId: string, date: string } Y { type: "Y", employeeId: string, date: string } Z { type: "Z", employeeId: strin

我有一个单独的存储桶(Couchbase Community edition 6.5),包含以下文档:

employee {
    type: "Employee"
}
X {
    type: "X",
    employeeId: string,
    date: string
}
Y {
    type: "Y",
    employeeId: string,
    date: string
}
Z {
    type: "Z",
    employeeId: string,
    date: string
}
我需要获取两个日期之间与每个员工关联的文档总数(X、Y、Z)

我编写了以下查询,但执行速度较慢:

CREATE INDEX `index_X` ON `bucket`(`type`,`date`, `employeeId`)
WHERE type = "X"
CREATE INDEX `index_Y` ON `bucket`(`type`,`date`, `employeeId`)
WHERE type = "Y"
CREATE INDEX `index_Z` ON `bucket`(`type`,`date`, `employeeId`)
WHERE type = "Z"

SELECT META(employee).id,
       x.totalX,
       y.totalY,
       z.totalZ,
FROM `bucket` employee 
    LEFT JOIN (
    SELECT obj.employeeId,
           COUNT(obj.employeeId) AS totalX
    FROM `bucket` obj
    WHERE obj.type = "X"
        AND obj.date BETWEEN "startDate" AND "endDate"
    GROUP BY obj.employeeId) x ON x.employeeId = META(employee).id 
    LEFT JOIN (
    SELECT obj.employeeId,
           COUNT(obj.employeeId) AS totalY
    FROM `bucket` obj
    WHERE obj.type = "Y"
        AND obj.date BETWEEN "startDate" AND "endDate"
    GROUP BY obj.employeeId) y ON y.employeeId = META(employee).id 
    LEFT JOIN (
    SELECT obj.employeeId,
           COUNT(obj.employeeId) AS totalZ
    FROM `bucket` obj
    WHERE obj.type = "Z"
        AND obj.date BETWEEN "startDate" AND "endDate"
    GROUP BY obj.employeeId) z ON z.employeeId = META(employee).id 
WHERE employee.type = "Employee"
我还尝试了以下操作,但此查询完全超时

CREATE INDEX `index_X` ON `bucket`(`type`,`date`, `employeeId`)
WHERE type = "X"
CREATE INDEX `index_Y` ON `bucket`(`type`,`date`, `employeeId`)
WHERE type = "Y"
CREATE INDEX `index_Z` ON `bucket`(`type`,`date`, `employeeId`)
WHERE type = "Z"

SELECT META(employee).id,
       COUNT(x.employeeId),
       COUNT(y.employeeId),
       COUNT(z.employeeId)
FROM `bucket` employee
    LEFT JOIN `bucket` x ON x.employeeId = META(employee).id
    AND x.type = "X"
    AND x.date BETWEEN "startDate" AND "endDate"
    LEFT JOIN `bucket` y ON y.employeeId = META(employee).id
    AND y.type = "Y"
    AND y.date BETWEEN "startDate" AND "endDate"
    LEFT JOIN `bucket` z ON z.employeeId = META(employee).id
    AND z.type = "Z"
    AND z.date BETWEEN "startDate" AND "endDate"
WHERE employee.type = "Employee"
GROUP BY META(employee).id
有谁能建议一条更为理想的路线吗

通过这两个查询,我可以看到我的索引正在被使用,但我也可以在我的查询计划中看到,对于每个连接,“NestedLoopJoin”都链接到上一个。这可能是问题所在吗

我还不熟悉编写n1ql查询,并尝试找出最有效的方法,因此欢迎提供任何建议

CREATE INDEX `index_1` ON `agrigistics_dev`(`employeeId`, type, `date`) WHERE type IN ["X", "Y", "Z"];

SELECT META(employee).id,
       SUM(CASE x.type = "X" THEN 1 ELSE 0 END) xcount,
       SUM(CASE x.type = "Y" THEN 1 ELSE 0 END) ycount,
       SUM(CASE x.type = "Z" THEN 1 ELSE 0 END) zcount
FROM `bucket` employee
LEFT JOIN `bucket` x
           ON x.employeeId = META(employee).id AND x.type IN ["X", "Y", "Z"] AND x.date BETWEEN "startDate" AND "endDate"
WHERE employee.type = "Employee"
GROUP BY META(employee).id;
为了避免cade嵌套循环联接或联接爆炸,在这种情况下使用CTE(6.5)

CREATE INDEX `index_1` ON `agrigistics_dev`(type, date, `employeeId`) WHERE type IN ["X", "Y", "Z"];

WITH etype AS (SELECT x.employeeId,
               SUM(CASE x.type = "X" THEN 1 ELSE 0 END) xcount,
               SUM(CASE x.type = "Y" THEN 1 ELSE 0 END) ycount,
               SUM(CASE x.type = "Z" THEN 1 ELSE 0 END) zcount
               FROM `bucket` x
               WHERE x.type IN ["X", "Y", "Z"] AND x.date BETWEEN "startDate" AND "endDate"
               GROUP BY x.employeeId)
SELECT META(employee).id,
       SUM(y.xcount) xcount,
       SUM(y.ycount) ycount,
       SUM(y.zcount) zcount
FROM `bucket` AS employee
LEFT JOIN etype AS y ON y.employeeId = META(employee).id
WHERE employee.type = "Employee"
GROUP BY META(employee).id;