Sla*_*mir 5 mysql stored-procedures jdbc mysql-5.5
在 Java 中,我们通过 JDBC 访问 MySQL (v5.5.40)——一个准备语句,设置参数然后调用存储过程。似乎每个 execute() 在实际 SP 调用之前都有 4 个元调用(每个 MySQL 查询日志)的开销:
SELECT name, type, comment FROM mysql.proc WHERE name like...
SHOW FUNCTION STATUS LIKE 'sp_one'
SHOW PROCEDURE STATUS LIKE 'sp_one'
SHOW CREATE PROCEDURE `db-name`.`sp_one`
CALL sp_one()
Run Code Online (Sandbox Code Playgroud)
这是服务器端的预期行为吗?只是看起来效率不高。
以下是我们如何使用 API 的示例:
conn = DriverManager.getConnection(..);
stmt = conn.prepareCall("{call sp_one(?,?)}");
stmt.setString(1, "a");
stmt.setString(2, "b");
stmt.execute();
Run Code Online (Sandbox Code Playgroud)
请注意以下情况是正确的:
谢谢!
Percona 写了一篇很好的文章MySQL 准备语句解释了优点和缺点
\n\n\n\n\n因此,有充分的理由使用准备好的语句:
\n\n\n
\n\n- \n
节省查询解析
- \n
节省数据转换和复制
- \n
避免 SQL 注入
- \n
节省处理 blob 的内存
使用准备好的语句也有缺点和困难:
\n\n\n
\n- \n
查询缓存不起作用
- \n
如果语句仅使用一次,则需要额外的服务器往返
- \n
并非所有报表都可以准备。因此,您可以\xe2\x80\x99t 专门使用准备好的API,您\xe2\x80\x99 需要针对某些语句回退到普通API
- \n
较新且有时有错误的代码。我在使用 PHP 准备好的语句时遇到了很多问题。它正在变得更好,但仍然不如标准 API 成熟
- \n
您可以\xe2\x80\x99t 使用占位符代替所有标识符。例如,您可以\xe2\x80\x99t 将它们用作表名。在某些版本中,它甚至不适用于 LIMIT 边界
- \n
列表处理不方便。与 PEAR 模拟\n 准备好的语句不同,没有很好的方法将值列表传递给 IN
- \n
更难追踪。日志现在已修复为包含完整的语句文本,不仅\n\n\xe2\x80\x9cExecute\xe2\x80\x9d,但在 SHOW INNODB STATUS 中,您仍然会看到\n没有实际值的语句\xe2\x80\x93,这对于分析来说非常不方便
由于您遇到的是预期行为,因此您不应使用准备语句。您正在进行多次调用来执行单个命令。如果你只是运行这个
\n\nstmt = conn.createStatement();\nrs = stmt.executeQuery("call sp_one(\'a\',\'b\')");\n
Run Code Online (Sandbox Code Playgroud)\n\nSQL的完整解析、执行准备以及SQL语句已经传入的参数都在服务器端通过一次调用完成。
\n\n\n