繁体   English   中英

您可以使查询更快吗?

[英]Can you make this query faster?

我目前正在做一个暑假工作,我必须扩展现有的程序。

我的老板要求我为我们的客户制作工具,以便他们可以看到他们的员工每月花费多少。 但这还不是全部。 问题是一家公司可以拥有一个或多个“社团”或子公司。 我们想知道员工在公司中每个社会的成本是多少。

这些是我使用的表:

  • 社团:带有people_id的子公司,其中包含社团的名称等
  • 时间表:包含人员和社会信息的时间表条目
  • 人员:数据库中的所有人员或联系人
  • 薪金状态:包含某人一个月的薪水
  • 间接费用:某人在特定月份的间接费用(请注意,日期是一个字符串(!),格式为:YYYY-MM-DD)

该查询有效,但是执行时间很长。 有没有办法使其更快?

我选择年份和月份,获得雇员(工人)的姓名和社团的名称。 然后,我选择员工(针对特定社会)工作的分钟总数。 最后,我通过检查他当月的工资和当月的间接费用来计算费用。

SELECT
    YEAR(TS.assigndate) AS timesheet_year,
    MONTH(TS.assigndate) AS timesheet_month,
    CONCAT(TP.name, ' ', TP.firstname) AS worker,
    CONCAT(SP.name, ' ', SP.firstname) AS society,
    (
        SELECT
            SUM(timeunits) AS minutes
        FROM timesheet
        WHERE
            people_id = TP.id AND
            society_id = S.id AND
            MONTH(assigndate) = timesheet_month
    ) AS minutes,
    (
        SELECT (minutes / 60)
    ) AS hours,
    (
        SELECT(OO.hourtarif + SS.hourtarif) AS cost
        FROM salarystate SS, overhead OO
        WHERE
            people_id = TP.id AND
            YEAR(OO.date) = timesheet_year AND
            MONTH(OO.date) = timesheet_month AND
            CONVERT(SUBSTRING(SS.month FROM 1 FOR 4), UNSIGNED) = timesheet_year AND
            CONVERT(SUBSTRING(SS.month, -2), UNSIGNED) = timesheet_month
    ) AS cost,
    (
        SELECT (hours * cost)
    ) AS total_cost
FROM timesheet TS, society S, people SP, people TP
WHERE
    S.id = TS.society_id AND
    SP.id = S.people_id AND
    TP.id = TS.people_id
GROUP BY timesheet_year, timesheet_month, worker, society; 
  1. 创建日期维度表http://www.sqlserversavvy.com/2008/03/t-sql-script-to-create-date-dimension.html
  2. 将与此日期列相关的列添加到此表
  3. 与dimDate分组

现在,我使用临时表,它会像地狱般快速:)。 如果您有兴趣,这是现​​在的代码:

CREATE TEMPORARY TABLE IF NOT EXISTS people_hours (
    people_id INTEGER NOT NULL,
    society_id INTEGER NOT NULL,
    year INTEGER NOT NULL,
    month INTEGER NOT NULL,
    hours DOUBLE NOT NULL,
    PRIMARY KEY(people_id, society_id, year, month)
);

CREATE TEMPORARY TABLE IF NOT EXISTS people_cost (
    people_id INTEGER NOT NULL,
    year INTEGER NOT NULL,
    month INTEGER NOT NULL,
    cost DOUBLE NOT NULL,
    PRIMARY KEY(people_id, year, month)
);

TRUNCATE people_hours;
TRUNCATE people_cost;

INSERT INTO people_hours (people_id, society_id, year, month, hours)
SELECT
    p.id as people_id,
    s.id as society_id,
    YEAR(t.assigndate) as year,
    MONTH(t.assigndate) as month,
    SUM(t.timeunits)/60 as hours
FROM people p, society s, timesheet t
WHERE
    t.society_id = s.id AND
    t.people_id = p.id
GROUP BY year, month, people_id, society_id;

INSERT INTO people_cost (people_id, year, month, cost)
SELECT
    p.id as people_id,
    YEAR(o.date) as cost_year,
    MONTH(o.date) as cost_month,
    SUM(o.hourtarif + s.hourtarif) as cost
FROM people p, salarystate s, overhead o
WHERE
    s.people_id = p.id AND
    CONVERT(SUBSTRING(s.month FROM 1 FOR 4), UNSIGNED) = YEAR(o.date) AND
    CONVERT(SUBSTRING(s.month, -2), UNSIGNED) = MONTH(o.date)
GROUP BY cost_year, cost_month, people_id;

SELECT 
    h.year,
    h.month,
    h.society_id,
    h.hours,
    c.cost,
    (h.hours * c.cost) AS total_cost,
    CONCAT(p.name, ' ', p.firstname) AS employee,
    CONCAT(ps.name, ' ', ps.firstname) AS society
FROM people_hours h, people_cost c, people p, people ps, society s
WHERE
    h.society_id = s.id AND
    h.people_id = p.id AND
    h.people_id = c.people_id AND
    s.people_id = ps.id AND
    h.year = c.year AND
    h.month = c.month
ORDER BY h.year, h.month, h.people_id, h.society_id;

暂无
暂无

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

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