如何提高复杂MySQL选择查询的性能?

时间:2017-04-07 12:56:50

标签: mysql

我正在研究项目管理工具,并且在通过管理员端生成报告时,来自数据库的数据的加载时间非常多。 5分钟。我知道有几点可以帮助我提高性能但是现在我需要在SELECT查询中获得帮助

SELECT timesheet_client.organisation as client_name, timesheet_project.title as project_name,
  timesheet_task.name as task, CONCAT(timesheet_user.first_name, ' ', timesheet_user.last_name) as resource_name,
  timesheet_user.bill_factor, timesheet_client.client_type, sum(spent) as spent, sum(delivered_hours) as delivered_hours, 
  sum(billable_hours) as billable_hours, comments, color, lock_color, updated_by, updated_by_date, timesheet_user_psdb.grp_id, 
  timesheet_user_psdb.client_id, timesheet_user_psdb.proj_id, timesheet_user_psdb.task_id, timesheet_user_psdb.uid, 
  timesheet_user_grp.grp_name
FROM timesheet_user_psdb,timesheet_user, timesheet_client, 
  timesheet_project,timesheet_task,timesheet_user_grp
WHERE timesheet_user.username=timesheet_user_psdb.uid and
  timesheet_client.client_id=timesheet_user_psdb.client_id and timesheet_project.proj_id=timesheet_user_psdb.proj_id and
  timesheet_task.task_id = timesheet_user_psdb.task_id and timesheet_user_grp.grp_id=timesheet_user_psdb.grp_id and month =3
  AND year = 2017 and month!='' and timesheet_user_psdb.client_id=326  
GROUP BY timesheet_user_psdb.task_id,timesheet_user_psdb.uid
ORDER BY timesheet_client.client_type desc,timesheet_client.organisation,timesheet_user_psdb.proj_id,
  timesheet_user_psdb.task_id,timesheet_user.uid,timesheet_user_psdb.task_id;

我已经在所有主键上使用了索引。

EXPLAIN输出: EXPLAIN Results for above statement

对此的帮助将非常值得注意。

2 个答案:

答案 0 :(得分:1)

执行EXPLAIN应该对它有所了解。

通过在FROM子句中显式执行表连接而不是在WHERE(https://dev.mysql.com/doc/refman/5.7/en/join.html)内部,您可能会看到性能提升。通过显式连接(例如,LEFT OUTER等),您不仅可以提高查询的可读性,还可以在需要时使用更便宜的连接。这也会影响查询的执行方式,因为每个子句都按特定顺序执行(MySQL query / clause execution order)。

答案 1 :(得分:1)

尝试一下:

SELECT 
    TC.ORGANISATION AS CLIENT_NAME, 
    TP.TITLE AS PROJECT_NAME,
    TT.NAME AS TASK, 
    CONCAT(TU.FIRST_NAME, ' ', TU.LAST_NAME) AS RESOURCE_NAME,
    TU.BILL_FACTOR, 
    TC.CLIENT_TYPE, SUM(SPENT) AS SPENT, -- You should specify which table this comes from
    SUM(DELIVERED_HOURS) AS DELIVERED_HOURS, -- You should specify which table this comes from
    SUM(BILLABLE_HOURS) AS BILLABLE_HOURS, -- You should specify which table this comes from
    COMMENTS, -- You should specify which table this comes from
    COLOR, -- You should specify which table this comes from
    LOCK_COLOR, -- You should specify which table this comes from
    UPDATED_BY, -- You should specify which table this comes from
    UPDATED_BY_DATE, -- You should specify which table this comes from
    TUP.GRP_ID, 
    TUP.CLIENT_ID, 
    TUP.PROJ_ID, 
    TUP.TASK_ID, 
    TUP.UID, 
    TUG.GRP_NAME
FROM    
    TIMESHEET_USER AS TU
        LEFT OUTER JOIN 
    TIMESHEET_USER_PSDB AS TUP
        ON TU.USERNAME = TUP.UID
        LEFT OUTER JOIN
    TIMESHEET_USER_GRP AS TUG
        ON TUP.GRP_ID = TUG.GRP_ID
        LEFT OUTER JOIN     
    TIMESHEET_CLIENT AS TC
        ON TUP.CLIENT_ID = TC.CLIENT_ID
        LEFT OUTER JOIN
    TIMESHEET_PROJECT AS TP
        ON TUP.PROJ_ID = TP.PROJ_ID
        LEFT OUTER JOIN
    TIMESHEET_TASK TT
        ON TUP.TASK_ID = TT.TASK_ID 
WHERE 
    MONTH = 3 AND -- You should specify which table this comes from
    YEAR = 2017 AND -- You should specify which table this comes from
    MONTH != '' AND -- You should specify which table this comes from
    TUP.CLIENT_ID = 326  
GROUP BY 
    TUP.TASK_ID,
    TUP.UID
ORDER BY 
    TC.CLIENT_TYPE DESC,
    TC.ORGANISATION,
    TUP.PROJ_ID,
    TUP.TASK_ID,
    TU.UID,
    TUP.TASK_ID;