SELECT
`User`.`id` AS id,
`User`.`f_name` AS name,
`User`.`l_name` AS surname,
`User`.`discharge` AS discharge, SUM(`Hour`.`normal`) + SUM(`Hour`.`full`) + SUM(`Hour`.`half`) workedHours,
(SUM(Hour.day_off_id = 16))*8 AS hourFracht
FROM `kadry`.`users` AS `User`
LEFT JOIN `kadry`.`Hours` AS `Hour` ON (`Hour`.`subordinate_id` = `User`.`id` AND DATE(`Hour`.`date`) BETWEEN '2016-06-01' AND '2016-06-30')
WHERE (`User`.`discharge` IS NULL OR DATE(`User`.`discharge`) > '2016-06-30') AND `User`.`role` = 'regular' AND `User`.`active` = '1'
GROUP BY `User`.`id`
ORDER BY `User`.`assigned` ASC, `User`.`l_name` ASC
我有这个属性的表:
CREATE TABLE `hours` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`date` DATE NOT NULL,
`hour_from` FLOAT NULL DEFAULT NULL,
`hour_to` FLOAT NULL DEFAULT NULL,
`subordinate_id` VARCHAR(11) NOT NULL,
`supervisor_id` VARCHAR(11) NOT NULL,
`max_synchro` TINYINT(1) NOT NULL DEFAULT '0',
`day_off_id` SMALLINT(2) NULL DEFAULT NULL,
`night` FLOAT NOT NULL DEFAULT '0',
`half` FLOAT NOT NULL DEFAULT '0',
`full` FLOAT NOT NULL DEFAULT '0',
`normal` FLOAT NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE INDEX `date` (`date`, `subordinate_id`),
INDEX `subordinate_id` (`subordinate_id`),
INDEX `supervisor_id` (`supervisor_id`),
INDEX `date_2` (`date`),
CONSTRAINT `users_id` FOREIGN KEY (`subordinate_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `userssupervisors` FOREIGN KEY (`supervisor_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=417864
;
表格时间有400k行以上查询需要10-13秒 我能做什么 ?添加更多索引或其他内容?
修改
CREATE TABLE `users` (
`id` VARCHAR(11) NOT NULL COLLATE 'utf8_general_ci',
`l_name` VARCHAR(80) NOT NULL COLLATE 'utf8_polish_ci',
`f_name` VARCHAR(80) NOT NULL COLLATE 'utf8_polish_ci',
`created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`department` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
`username` VARCHAR(40) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`password` VARCHAR(40) NOT NULL DEFAULT '' COLLATE 'utf8_general_ci',
`role` ENUM('admin','regular','superior','manager') NOT NULL DEFAULT 'regular' COLLATE 'utf8_general_ci',
`assigned` VARCHAR(15) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`discharge` DATE NULL DEFAULT NULL,
`active` TINYINT(1) NOT NULL DEFAULT '1',
`last_entry` DATE NULL DEFAULT NULL,
`in_use` VARCHAR(11) NOT NULL DEFAULT '0' COLLATE 'utf8_general_ci',
`info` TEXT NULL COLLATE 'utf8_polish_ci',
`id_user_card` INT(11) NULL DEFAULT NULL,
`email` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`include_raport` TINYINT(1) NOT NULL DEFAULT '1',
`in_collections` TINYINT(1) NOT NULL DEFAULT '1',
`locker_number` INT(11) UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `assigned` (`assigned`),
INDEX `role` (`role`),
INDEX `active` (`active`),
INDEX `id_index` (`id`),
INDEX `discharge` (`discharge`),
CONSTRAINT `department_id3` FOREIGN KEY (`assigned`) REFERENCES `departments` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_polish_ci'
ENGINE=InnoDB
;
答案 0 :(得分:0)
首先,我会用表别名重写查询,以便更容易阅读:
SELECT u.id, u.f_name AS name, u.l_name AS surname, u.discharge,
SUM(h.`normal`) + SUM(h.`full`) + SUM(h.`half`) as workedHours,
SUM(h.day_off_id = 16) * 8 AS hourFracht
FROM `kadry`.`users` u LEFT JOIN
`kadry`.`Hours` h
ON (h.subordinate_id = u.id AND
DATE(h.date) BETWEEN '2016-06-01' AND '2016-06-30')
WHERE (u.discharge IS NULL OR DATE(u.discharge) > '2016-06-30') AND
u.`role` = 'regular' AND u.`active` = '1'
GROUP BY u.id
ORDER BY u.`assigned` ASC, `User`.`l_name` ASC;
索引可以提供帮助。我建议:users(role, active, discharge, id)
和hours(subordinate_id, date)
。