并发存储过程执行期间MySQL性能下降

时间:2017-07-03 12:03:44

标签: mysql performance stored-procedures explain

机器规格: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

1 个答案:

答案 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许多人:很多。

在完成所有这些之后,如果它仍然存在,我们可以继续讨论你的时间异常。