机器规格:macOS Sierra,版本10.12.5,内存8 GB
MySQL版本: MySQL企业服务器 - 高级版(商业)3 innodb_version:5.7.18
问题:当不同会话同时调用相同的存储过程时,响应时间会延迟很多。
以下SQL是每次执行需要0.12秒的SQL。为了模拟这个问题,我在一个while循环中运行下面的SQL,迭代30次,从而每次执行存储过程平均需要3秒。
但是,当我从不同的终端/会话中同时运行相同的存储过程时,两个存储的过程几乎都需要 50秒。
表以innodb创建,缓冲区大小和读/写io用普通值设置。
查询
SELECT MIN(BEGIN_date) , MAX(END_date)
FROM employee e, department d
WHERE e.employee_ID = d.employee_ID
AND d.Department_ID = 72641 ;
解释扩展计划如下(索引被完美使用)
----+-------------+-------+------------+------+------------------+---------- --------+---------+-------------------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+------------------+------------------+---------+-------------------------------+------+----------+-------------+
| 1 | SIMPLE | d | NULL | ref | deptmnt_dept_idx | deptmnt_dept_idx | 4 | const | 808 | 100.00 | NULL |
| 1 | SIMPLE | e | NULL | ref | Emp_Name_Dt _idx | Emp_Name_Dt _idx | 4 | radar_bridge_db.d.Employee_ID | 156 | 100.00 | Using index |
+----+-------------+-------+------------+------+------------------+------------------+---------+-------------------------------+------+----------+-------------+
存储过程
CREATE PROCEDURE `fetchEmployeeDetails`()
BEGIN
DECLARE l_StartDate DATE DEFAULT CURRENT_DATE()-INTERVAL 7 DAY;
DECLARE l_EndDate DATE DEFAULT CURRENT_DATE();
DECLARE I_Range INT DEFAULT 0;
WHILE I_Range < 30 DO
SELECT MIN(BEGIN_date) , MAX(END_date)
INTO l_StartDate, l_EndDate FROM employee e, department d
WHERE e.employee_ID = d.employee_ID AND d.Department_ID = 72641 ;
SET I_Range = I_Range + 1;
END WHILE;
END;
当从不同的终端/会话同时调用相同的SP时,两个SP都需要将近50秒。
示例在同一台Mac机上的MySQL社区版和企业版(线程池都启动)上运行,但问题仍然存在。 如果您有任何方法可以解决此性能问题,请与我们联系。
CREATE TABLE `employee` (
`COMPANY_ID` int(11) NOT NULL,
`COMPANY_NAME` varchar(255) CHARACTER SET utf8 NOT NULL,
`EMPLOYEE_ID` int(11) NOT NULL,
`BEGIN_DATE` timestamp NULL DEFAULT NULL,
`END_DATE` timestamp NULL DEFAULT NULL,
KEY `Emp_Name_Dt_idx` (`EMPLOYEE_ID`,`BEGIN_DATE`,`END_DATE`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `department` (
`Employee_ID` int(11) NOT NULL,
`Department_ID` int(11) NOT NULL,
KEY `deptmnt_dept_idx` (`Department_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
答案 0 :(得分:0)
请重新考虑架构。
名为employee
的表应该谈论一个人。如果这个人被多次雇用,你所拥有的似乎有多行。也许它应该被称为tenure
,并与employee
分开。
department
应该是一个部门。你拥有的是很多:员工和部门之间的许多映射。但是,员工可以属于多个部门吗?如果没有,那么它是1:多的映射,并且不需要该表。取而代之的是department_id
表中的employee
。
而且,每张桌子都需要PRIMARY KEY
:
PRIMARY KEY(employee_id) -- on employee
PRIMARY KEY(employee_id, start_date, end_date) -- on tenure
PRIMARY KEY(department_id) -- on department
PRIMARY KEY(department_id, employee_id) -- on many:many mapping
INDEX(department_id) -- on employee, if 1:many
INDEX(employee_id, department_id) -- if many:many
More discussion许多人:很多。
在完成所有这些之后,如果它仍然存在,我们可以继续讨论你的时间异常。