简体   繁体   English

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

[英]How to increase performance of complicated MySQL select query?

I am working on project management tool and while generating reports through admin end the loading time for the data from the database is very much > 5 minutes. 我正在使用项目管理工具,并且在通过管理端生成报告时,从数据库中加载数据的时间非常多> 5分钟。 There are few points which I know would help me to increase the performance but right now I need to have the help in SELECT query 我知道有几点可以帮助我提高性能,但是现在我需要在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;

I have already used an index on all the primary keys. 我已经在所有主键上使用了索引。

EXPLAIN Output: 解释输出: 解释以上陈述的结果

Help for this would be highly appreciable. 对此的帮助将非常可观。

Doing the EXPLAIN should shed some light on it. 做EXPLAIN应该会有所启发。

You might see a performance gain by doing the table joins explicitly in the FROM clause instead of inside the WHERE ( https://dev.mysql.com/doc/refman/5.7/en/join.html ). 通过在FROM子句中而不是在WHERE内部进行表联接,您可能会看到性能提高( https://dev.mysql.com/doc/refman/5.7/en/join.html )。 By doing explicit joins (eg LEFT OUTER, etc...) you will not only improve the readability of the query, but may be able to use less expensive joins where needed. 通过执行显式联接(例如LEFT OUTER等),您不仅可以提高查询的可读性,而且可以在需要的地方使用较便宜的联接。 This also affects how the query is executed as each clause is executed in a specific order ( MySQL query / clause execution order ). 这也会影响查询的执行方式,因为每个子句都以特定顺序执行( MySQL查询/子句执行顺序 )。

Give this a try: 试试看:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM