【发布时间】:2017-12-06 16:42:05
【问题描述】:
机器规格:macOS Sierra,版本 10.12.5,内存 8 GB
MySQL 版本: MySQL Enterprise Server - 高级版(商业版)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
【问题讨论】:
-
请提供
SHOW CREATE TABLE和/或限定所有列,以便我们知道END_date在哪个表中!没有这个,我们无法给你答案! -
为什么循环运行 30 次?似乎每次都给出相同的结果!
-
感谢 Rick 对此进行调查。我正在运行 30 次,以便让我有一个窗口期(即 3 秒)来获得另一个并发执行运行。还按要求将创建表 DDL 添加到问题中。
-
另请注意,某些存储过程的并发执行确实挂起,即使它们在单独执行时工作正常(
-
您是否尝试过在其他操作系统(Mac 除外)中进行性能比较?
标签: mysql performance stored-procedures explain