dav*_*nes 1 mysql sql optimization
我通常在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
Run Code Online (Sandbox Code Playgroud)
编辑:解释输出
"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"
Run Code Online (Sandbox Code Playgroud)
如果在对非索引的列组合进行分组时聚合值,则SQL引擎将创建临时表作为其正常运行的一部分,以便保存部分聚合的值.你有两个和以及需要的每种组合来计算的计数company.tblusers.userid和db.batches.operation_id.必须存储这些值,因为很明显,没有包含这两列的索引,因为它们位于不同的表中.
我不知道它为什么会死,除非它实际上是因为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
Run Code Online (Sandbox Code Playgroud)
UPDATE
根据explain-plan结果,您没有查询可以使用的任何索引ncr_ncr.这是不好的.它实际上是创建了一个可以排序的表的新副本,employee以便可以在合理的时间内进行连接.
即使该表不是很大(只有2700行),你仍然需要放一个索引(最好是相关的,如果系统的其余部分允许它)db2.ncr_ncr.employee,否则你的性能将受到严重影响.这个表足够小,制作和排序临时副本应该不是问题,但它仍然会损害您的性能.
同样如此batch_log.userid.