存储过程的一个好处是速度快。我跑了一些测试并得到了一些奇怪的结果!
场景:有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或系统环境导致它? 据我所知SP对于简单查询非常有用,但这里......
请注意,经过3次运行后,上述时间已被记录下来。
由于 AHHP
答案 0 :(得分:3)
首先:缓存查询。不止一次运行它们将主要向您显示MySQL从缓存中检索其先前结果的速度。您可以在SQL_NO_CACHE
关键字后添加SElECT
来阻止这种情况(
然后,存储过程的速度与它们执行的代码一样快。如果在存储过程中执行查询,它将永远不会比查询更快。它仍然是相同的查询,但运行存储过程会产生一些额外的开销。
如果不从存储过程返回数据,它看起来会更快。执行的查询的结果将发送给调用者。如果你不在存储过程中这样做,你获得的速度只是因为发送的数据较少。
然后,您在存储过程中执行的查询与单独的查询不同。在单独的查询中,您在查询字符串发送到MySQL之前输入确切的值,而在存储过程中,您实际上有一个参数化查询,您将该值作为参数填充到mysql引擎(尽管这个事实是通过在存储过程中调用查询的语法隐藏了一点。这意味着第一次调用这些过程会导致MySQL必须再次解析该查询,而'常量值'版本已经被缓存。
总之,你的测试是错误的。
如果您需要执行一些无法在单个查询中执行的处理或过滤,则存储过程 更快。将所有数据提取到PHP并在那里处理它会导致在PHP和MySQL之间来回发送太多数据。如果你在存储过程中进行所有处理,并且只发送(小)结果,这会更快,但主要是因为所有处理都保留在SQL引擎内部,所以没有序列化/反序列化,也没有来回发送数据。 / p>