【问题标题】:MySQL Simple Select - Stored Procedure PerformanceMySQL 简单选择 - 存储过程性能
【发布时间】:2013-04-26 15:40:47
【问题描述】:

我目前正在 MySQL 上开发一个存储过程,我期望速度会略有提高。 但是当我将它与通过 PHP 脚本执行 SQL 请求进行比较时,PHP 更快。使用 1000 行的表大约快 10 倍,使用 6000 行的表大约快 2 倍。

表的大小是否提高了程序的性能? 我的代码是否有错误,我可以对其进行优化吗?

我的配置是 MySQL 5.0.10 上的 MyIsam 引擎。 我的存储过程是

CREATE PROCEDURE  get_task (IN var INT)
BEGIN
    DECLARE id_task INT (11);
    DECLARE job INT (11);
    DECLARE state_name VARCHAR(20);
    DECLARE task_name VARCHAR(20);
    DECLARE worker_affected INT(11);
    DECLARE user VARCHAR(10);
    DECLARE progress INT(11);
    DECLARE name VARCHAR(128);
    DECLARE phone VARCHAR(128);
    DECLARE mobile VARCHAR(128);
    DECLARE site VARCHAR(32);
    DECLARE worker_name VARCHAR(20);
    DECLARE date_time_process_started DATETIME;
    DECLARE frame INT(11);

    DECLARE curseur1 CURSOR FOR 

    SELECT tq.`id_task`, tq.`job`, lts.`state_name`, ltt.`task_name`, tq.`worker_affected`, j.`user`, tq.`progress`, u.`name`, u.`phone`, u.`mobile`, u.`site`, w .`worker_name`, tq.`date_time_process_started`, tq.`frame`
    FROM `task_queue` tq
    LEFT JOIN `workers` w ON tq.`worker_affected` = w.`id_worker`
            INNER JOIN `job` j ON tq.`job` = j.`job_id`
            INNER JOIN `user` u ON j.`user` = u.`ipn`
            INNER JOIN `list_task_type` ltt ON tq.`task_type` = ltt.`id_type_task`
            INNER JOIN `list_task_state` lts ON tq.`task_state` = lts.`id_state`
    WHERE tq.`id_task` =  var 
    ORDER BY tq.`id_task`;

    OPEN curseur1;

    FETCH curseur1 INTO id_task, job, state_name, task_name, worker_affected, user, progress, name, phone, mobile, site, worker_name, date_time_process_started, frame;
    SELECT id_task, job, state_name, task_name, worker_affected, user, progress, name, phone, mobile, site, worker_name, date_time_process_started, frame;

    CLOSE curseur1;

END |

【问题讨论】:

  • 如果只有一行,请改用 SELECT INTO 语句。

标签: mysql performance stored-procedures


【解决方案1】:

我听从了您的建议,删除了 CURSOR 和声明。

CREATE PROCEDURE  get_task (IN var INT)
BEGIN

SELECT tq.`id_task`, tq.`job`, lts.`state_name`, ltt.`task_name`, tq.`worker_affected`, j.`user`, tq.`progress`, u.`name`, u.`phone`, u.`mobile`, u.`site`, w .`worker_name`, tq.`date_time_process_started`, tq.`frame`
FROM `task_queue` tq
LEFT JOIN `workers` w ON tq.`worker_affected` = w.`id_worker`
        INNER JOIN `job` j ON tq.`job` = j.`job_id`
        INNER JOIN `user` u ON j.`user` = u.`ipn`
        INNER JOIN `list_task_type` ltt ON tq.`task_type` = ltt.`id_type_task`
        INNER JOIN `list_task_state` lts ON tq.`task_state` = lts.`id_state`
WHERE tq.`id_task` =  var 
ORDER BY tq.`id_task`;


END |

确实性能飙升,现在我的存储过程只比 PHP 脚本慢两倍(0.0006 秒对 0.0012 秒,而之前的 0.0006 秒对 0.009 秒)。

看到存储过程的代码我明白你为什么说它没用了,但我会保留它,以迫使数据库用户通过他们网站中的函数和过程。这样我就更有安全感了。

非常感谢。

【讨论】:

  • 在存储过程中封装单个SELECT 似乎是不必要的复杂性和开销,除非您想从用户没有SELECT 权限的表中SELECT(并且您使用SQL SECURITY DEFINER).
【解决方案2】:

您编写的存储过程完全没有必要。

您不仅不需要CURSOR 来返回结果集,甚至不需要过程,只需运行单个SELECT 语句即可。

只需在您的 PHP 代码中包含 SELECT

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 2011-01-07
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    相关资源
    最近更新 更多