N1ql 计算不同的关联文档
N1ql count distinct associated documents
我有一个存储桶(Couchbase 社区版 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;
为了避免 case-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;
https://index-advisor.couchbase.com/indexadvisor/#1
https://blog.couchbase.com/create-right-index-get-right-performance/
我有一个存储桶(Couchbase 社区版 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;
为了避免 case-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;
https://index-advisor.couchbase.com/indexadvisor/#1
https://blog.couchbase.com/create-right-index-get-right-performance/