存储过程的优点之一是速度快。我做了一些测试,得到了一些奇怪的结果!
场景:有2个InnoDB表,代理和公司。每个代理通过FK与一家公司相关,索引正确。请看下面的方法:
两个简单查询:
$agent = $pdo->query("SELECT * FROM agents WHERE id=3")->fetch(PDO::FETCH_ASSOC);
$company = $pdo->query("SELECT name FROM companies WHERE id='$agent[company]'")->fetch(PDO::FETCH_ASSOC);
$name = $company['name'];
// 0.000793933868408
// 0.000741958618164
一个JOIN查询
$agent = $pdo->query("
SELECT agents.*, companies.name FROM agents
LEFT JOIN companies ON companies.id=agents.company
WHERE agents.id=3
")->fetch(PDO::FETCH_ASSOC);
$name = $agent['name'];
// 0.000327110290527
// 0.00028395652771
两个SP调用:
$agent = $pdo->query("CALL agents('3')")->fetch(PDO::FETCH_ASSOC);
$partner = $pdo->query("CALL companies('$agent[company]')")->fetch(PDO::FETCH_ASSOC);
$name = $agent['name'];
// 0.010176897049
// 0.010200023651
/*
CREATE PROCEDURE `agents`(agent INT(10))
BEGIN SELECT * FROM agents WHERE id=agent; END
CREATE PROCEDURE `companies`(company INT(10))
BEGIN SELECT * FROM companies WHERE id=company; END
*/
一个带有JOIN:
的SP调用$agent = $pdo->query("CALL agents('3')")->fetch();
$name = $agent['name'];
// 0.00241208076477
// 0.00252604484558
/*
CREATE PROCEDURE `agents`(agent INT(10))
BEGIN
SELECT agents.*, companies.name FROM agents
LEFT JOIN companies ON companies.id=agents.company
WHERE agents.id=agent;
END
*/
为什么这些简单的sp会像你看到的那样慢?是PDO还是系统环境导致的?据我所知,SPs对于简单查询非常有效,但这里.....
请注意,以上时间是运行3次后才记录的。
谢谢AHHP
第一:查询被缓存。多次运行它们将主要向您展示MySQL从缓存中检索先前结果的速度有多快。您可以通过在SElECT
关键字后添加SQL_NO_CACHE
来防止这种情况(一点)。
那么,存储过程的速度只和它们执行的代码一样快。如果在存储过程中执行查询,它永远不会比查询快。它仍然是同一个查询,但是增加了运行存储过程的一些额外开销。
如果不从存储过程返回数据,看起来会更快。执行查询的结果被发送给调用者。如果您在存储过程中不这样做,那么您获得的速度只是因为发送更少的数据。
那么,在存储过程中执行的查询与单独的查询不同。单独的查询,在查询字符串中输入的值之前,发送到MySQL,在存储过程时,你实际上有一个参数化查询台padd上阅读清单的值作为参数MySQL引擎(虽然这个事实隐藏一点的语法调用存储过程查询。这意味着第一次调用这些过程,导致MySQL来解析,再次查询,而常数值的版本已经缓存。
总之,你的测试是错误的。
如果您需要做一些不能在单个查询中完成的处理或过滤,则存储过程更快。将所有数据提取到PHP并在那里进行处理,会导致太多数据在PHP和MySQL之间来回发送。如果您在存储过程中完成所有处理,并且只发送(小)结果,这样会更快,但主要是因为所有处理都留在SQL引擎内部,因此没有序列化/反序列化,也没有来回发送数据。