I have a problem on this query as I don’t know now how to optimize it to make it faster
it takes 20 seconds to load
Employee Attendance View
SELECT
`datetimerecords`.`eid` AS `eid`,
`datetimerecords`.`timedate` AS `timedate`,
`datetimerecords`.`state` AS `state`,
`employees`.`employeeid` AS `employeeid`,
`employees`.`fullname` AS `fullname`,
`employees`.`position` AS `position`,
`departments`.`did` AS `did`,
`departments`.`departmentname` AS `departmentname`,
`schoolyear`.`syid` AS `syid`,
`schoolyear`.`school_year_name` AS `school_year_name`,
`schoolyear`.`school_year_quarter` AS `school_year_quarter`
FROM
(
(
( `datetimerecords` JOIN `employees` ON ( `datetimerecords`.`eid` = `employees`.`employeeid` ) )
JOIN `schoolyear` ON ( `datetimerecords`.`syid` = `schoolyear`.`syid` )
)
JOIN `departments` ON ( `employees`.`did` = `departments`.`did` )
)
ORDER BY
`datetimerecords`.`timedate`
Employees Table
CREATE TABLE `employees` (
`eid_non` int(11) NOT NULL AUTO_INCREMENT,
`did` int(11) DEFAULT NULL,
`esid` int(11) DEFAULT NULL,
`employeeid` varchar(255) DEFAULT NULL COMMENT 'eid',
`fullname` varchar(255) DEFAULT NULL,
`contactnumber` text DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`position` varchar(255) DEFAULT NULL,
PRIMARY KEY (`eid_non`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1290 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci ROW_FORMAT=DYNAMIC;
datetimerecords
CREATE TABLE `datetimerecords` (
`aid` int(11) NOT NULL AUTO_INCREMENT,
`eid` int(11) DEFAULT NULL,
`syid` int(11) DEFAULT NULL,
`timedate` varchar(255) DEFAULT NULL,
`state` varchar(255) DEFAULT NULL,
`datecreated` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`aid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=266387 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci ROW_FORMAT=DYNAMIC;
departments
CREATE TABLE `departments` (
`did` int(11) NOT NULL AUTO_INCREMENT,
`departmentname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`did`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci ROW_FORMAT=DYNAMIC;
Schoolyear Table
CREATE TABLE `schoolyear` (
`syid` int(11) NOT NULL AUTO_INCREMENT,
`school_year_name` varchar(255) DEFAULT NULL,
`school_year_quarter` varchar(255) DEFAULT NULL,
`is_default` enum('yes','no') NOT NULL DEFAULT 'no',
`datecreated` datetime DEFAULT NULL,
PRIMARY KEY (`syid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci ROW_FORMAT=DYNAMIC;
Have another type of query that can make it faster
2
Answers
Using EXPLAIN to show the query optimization strategy, we see two tables doing table-scans (
type: ALL
). That’s a common performance problem.The other joins are
eq_ref
which is a unique key lookup. That’s optimized about as well as we can hope.Two fixes are needed:
First, add an index on
employees(employeeid)
so the join can do a lookup efficiently.But this is not enough, because your join condition is comparing an
INT
column (datetimerecords.eid
) to aVARCHAR
column (employees.employeeid
).You can resolve this either by altering the data type in one or the other table, so they match.
You can also resolve it for this query alone by casting the
eid
column to a string.With these changes, the EXPLAIN shows that the first join is now doing a lookup on the non-unique index (
type: ref
).Give that a try and see if it makes the query perform well enough for your needs.
Indexes:
Why isn’t
employeeid
thePRIMARY KEY
ofemployees
? Might it not be unique? Might it beNULL
? Does it really need to beVARCHAR(255)
?