所以我有一个相对简单的查询,它根据WHERE为一系列输入选择存储函数的结果。完整的代码如下。查询在phpmyadmin中需要28秒,但mysql命令行需要662秒
什么是我当我通过mysql cli调用查询时,需要662秒才能返回一列中的841行。现在,如果我将相同的代码复制/粘贴到phpmyadmin中,相同的值将在28秒内返回。
我需要做什么才能使mysql像phpmyadmin一样快速执行此查询?
什么我已经尝试过:
- 证实,双方的phpmyadmin和PHP CLI使用相同
EXPLAIN
计划。EXPLAIN
计划现包含在下面。
- 已验证phpmyadmin和php cli都以同一用户身份执行查询。
- 测试mysql cli是否比php cli有更好的性能。
- 结果: mysql cli在661sec返回值,这可能与php cli的速度相同。我刚刚意识到
SHOW PROCESSLIST
在进程进入睡眠状态后会持续计数时间。 上面的问题标题和说明已被修改。
- 结果: mysql cli在661sec返回值,这可能与php cli的速度相同。我刚刚意识到
目前正在探索:
- 编辑存储功能,使而不是使用
WHERE IN
它使用WHERE EXISTS
。
整个查询建议:(包括没有问题的字段)
SELECT
EC_ITM_PULL.SKU_NUM,
EC_ITM_PULL.COLOR_CD,
GM_SKU.COLOR_DES,
GM_ITM.DES1,
GM_ITM.DES2,
CUSTOM.EC_GET_ONHAND(SUBSTRING(GM_SKU.SKU_NUM, 1, 9), GM_SKU.COLOR_CD) OH,
UPPER(EC_ITM_PULL.ITEM_PULLED_INIT) INIT,
CUSTOM.EC_MOST_RECENT_EVENT(SUBSTRING(GM_SKU.SKU_NUM, 1, 9), GM_SKU.COLOR_CD, 'E') EVENT_CD
FROM
EC_ITM_PULL,
GM_MERCH.GM_SKU,
GM_INV.GM_ITM,
EC_ITM
WHERE
EC_ITM.SKU_NUM = EC_ITM_PULL.SKU_NUM
AND EC_ITM_PULL.COLOR_CD = EC_ITM.COLOR_CD
AND EC_ITM_PULL.ITEM_PULLED IS NOT NULL
AND GM_ITM.ITM_CD = SUBSTRING(EC_ITM.SKU_NUM, 1, 9)
AND EC_ITM.SKU_NUM = GM_SKU.SKU_NUM
AND EC_ITM.TO_STUDIO IS NULL
AND GM_ITM.ITM_CD = SUBSTRING(EC_ITM_PULL.SKU_NUM, 1, 9);
查询说明计划:
+----+-------------+-------------+--------+---------------+---------+---------+-----------------------------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+--------+---------------+---------+---------+-----------------------------------------------------+------+-------------+
| 1 | SIMPLE | EC_ITM_PULL | ALL | SKU_NUM | NULL | NULL | NULL | 2100 | Using where |
| 1 | SIMPLE | GM_ITM | eq_ref | PRIMARY | PRIMARY | 38 | func | 1 | Using where |
| 1 | SIMPLE | GM_SKU | ref | SKU_NUM | SKU_NUM | 38 | CUSTOM.EC_ITM_PULL.SKU_NUM | 1 | |
| 1 | SIMPLE | EC_ITM | eq_ref | PRIMARY | PRIMARY | 58 | GM_MERCH.GM_SKU.SKU_NUM,CUSTOM.EC_ITM_PULL.COLOR_CD | 1 | Using where |
+----+-------------+-------------+--------+---------------+---------+---------+-----------------------------------------------------+------+-------------+
疑难存储函数:
CREATE DEFINER=`root`@`localhost` FUNCTION `EC_GET_ONHAND`(`N_ITM_CD` VARCHAR(12), `N_COLOR_CD` VARCHAR(6)) RETURNS smallint(5)
BEGIN
DECLARE TOTALOH SMALLINT(5);
IF N_COLOR_CD IS NULL THEN SELECT IFNULL(SUM(IFNULL(RESERVE_QTY,0)+IFNULL(AVAIL_QTY,0)),0)
INTO TOTALOH FROM GM_INV.GM_INV_LOC
WHERE SKU_NUM
IN (
SELECT SKU_NUM
FROM GM_MERCH.GM_SKU
WHERE ITM_CD = N_ITM_CD AND COLOR_CD IS NULL
)
AND (
(
(
STORE_CD='85'
OR STORE_CD='95'
)
AND LOC_CD='STG72'
)
OR (
(
STORE_CD='72'
)
AND LOC_CD='RCV'
)
);
ELSE SELECT IFNULL(SUM(IFNULL(RESERVE_QTY,0)+IFNULL(AVAIL_QTY,0)),0)
INTO TOTALOH
FROM GM_INV.GM_INV_LOC
WHERE SKU_NUM
IN (
SELECT SKU_NUM
FROM GM_MERCH.GM_SKU
WHERE ITM_CD = N_ITM_CD
AND COLOR_CD = N_COLOR_CD)
AND (
(
(
STORE_CD='85'
OR STORE_CD='95'
)
AND LOC_CD='STG72'
)
OR (
(
STORE_CD='72'
)
AND LOC_CD='RCV'
)
);
END IF;
RETURN TOTALOH;
END
功能EXPLAIN PLAN:
+----+--------------------+------------+----------------+---------------+---------------+---------+------------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+----------------+---------------+---------------+---------+------------------+--------+--------------------------+
| 1 | PRIMARY | GM_INV_LOC | ALL | NULL | NULL | NULL | NULL | 509791 | Using where |
| 2 | DEPENDENT SUBQUERY | GM_SKU | index_subquery | SKU_ITM_COLOR | SKU_ITM_COLOR | 97 | func,const,const | 1 | Using index; Using where |
+----+--------------------+------------+----------------+---------------+---------------+---------+------------------+--------+--------------------------+
只是一个想法,但它可能是不同的RAM分配或类似的东西? – Salketer 2014-12-04 15:22:01
您能否从'explain'方法提供执行计划?还有一些'mysqli'代码? – 2014-12-04 15:22:36
你在执行这个查询的地方在你的php函数中执行任何其他动作吗? – MTahir 2014-12-04 15:39:28