我通常在java中完成大部分工作,我无法真正找到我在这里做的事情,导致它需要复制到桌面并死掉。
SELECT company.tblusers.userid,
db.operations.id AS operation_id,
SUM(TIME_TO_SEC(db.batch_log.time_elapsed)) AS time_elapsed,
SUM(db.tasks.estimated_nonrecurring + db.tasks.estimated_recurring) AS total_elapsed,
COUNT(db2.ncr_ncr.id) AS number_of_ncrs
FROM company.tblusers
INNER JOIN db.operations
INNER JOIN db.batch_log ON company.tblusers.userid = batch_log.userid
INNER JOIN db.batches ON batch_log.batch_id = batches.id
INNER JOIN db.tasks ON db.batches.id = db.tasks.batch_id
INNER JOIN db2.ncr_ncr ON company.tblusers.sugar_name = db2.ncr_ncr.employee
WHERE company.tblusers.departmentid = 8
AND db.operations.id = db.batches.operation_id
AND db.batches.id = db.tasks.batch_id
AND db.batch_log.userid = company.tblusers.userid
AND db2.ncr_ncr.employee = company.tblusers.sugar_name
GROUP by company.tblusers.userid, db.batches.operation_id
编辑:解释输出
"id";"select_type";"table";"type";"possible_keys";"key";"key_len";"ref";"rows";"Extra"
"1";"SIMPLE";"ncr_ncr";"ALL";NULL;NULL;NULL;NULL;"2700";"Using temporary; Using filesort"
"1";"SIMPLE";"batch_log";"ALL";NULL;NULL;NULL;NULL;"78026";""
"1";"SIMPLE";"tblusers";"eq_ref";"PRIMARY";"PRIMARY";"52";"ramses.batch_log.userid";"1";"Using where"
"1";"SIMPLE";"tasks";"ref";"Index 2";"Index 2";"38";"ramses.batch_log.batch_id";"2";""
"1";"SIMPLE";"batches";"eq_ref";"PRIMARY";"PRIMARY";"38";"ramses.tasks.batch_id";"1";"Using where"
"1";"SIMPLE";"operations";"eq_ref";"PRIMARY";"PRIMARY";"4";"ramses.batches.operation_id";"1";"Using where; Using index"
答案 0 :(得分:8)
如果在对非索引的列组合进行分组时聚合值,则SQL引擎将创建临时表作为其正常运行的一部分,以便保存部分聚合的值。您需要为company.tblusers.userid
和db.batches.operation_id
的每个组合计算两个SUM和一个COUNT。必须存储这些值,因为很明显,没有包含这两列的索引,因为它们位于不同的表中。
我不知道它为什么会死,除非它实际上是因为COUNT聚合而将完整连接构建为临时表。
您可能只应将其作为相关子查询,而不是加入db2.ncr_ncr表。这可能需要更少的存储空间:
SELECT
company.tblusers.userid,
db.operations.id AS operation_id,
SUM(TIME_TO_SEC(db.batch_log.time_elapsed)) AS time_elapsed,
SUM(db.tasks.estimated_nonrecurring + db.tasks.estimated_recurring) AS total_elapsed,
(SELECT COUNT(*) FROM db2.ncr_ncr WHERE db2.ncr_ncr.employee = company.tblusers.sugar_name) AS number_of_ncrs
FROM
company.tblusers
INNER JOIN db.batch_log ON batch_log.userid = company.tblusers.userid
INNER JOIN db.batches ON db.batches.id = db.batch_log.batch_id
INNER JOIN db.operations ON db.operations.id = db.batches.operation_id
INNER JOIN db.tasks ON db.tasks.batch_id = db.batch_log.batch_id
WHERE
company.tblusers.departmentid = 8
GROUP BY
company.tblusers.userid,
db.batches.operation_id
<强>更新强>
根据解释计划结果,您没有查询可以在ncr_ncr
上使用的任何索引。这是不好的。它实际上创建了一个表的新副本,它可以按employee
排序,以便可以在合理的时间内进行连接。
即使该表不是很大(只有2700行),你仍然需要在db2.ncr_ncr.employee
上放置一个索引(最好是相关的,如果系统的其余部分允许它),否则你的性能将会受苦受难。这个表足够小,制作和分类临时副本不应该是一个问题,但它仍然会损害你的表现。
batch_log.userid
也是如此。