我们注意到性能不是很好,但没有那么多打扰我们,因为它是一个后台进程,然后我们的DBA联系了我们,他告诉我们每个存储过程调用都是跨越第二次调用以从中获取元数据DB。
显然我们的代码中没有任何地方可以进行任何此类调用,不,我们没有使用任何可能在幕后发布它们的ORM框架。
这是我们的设置: - 独立(无容器)Java应用程序 - spring-jdbc-3.2.2用于数据访问 - 我们正在使用Microsoft JDBC Driver 4.0 for SQL Server - 我们正在使用以下语法:CALL SPROC_NAME(:PAR_1)
有关如何删除此额外调用的任何指示都非常感谢。我无法打开SQL Server驱动程序的日志记录,因此我的下一步是尝试调试spring JDBC代码。
谢谢, MV
答案 0 :(得分:1)
就像我说的那样,每次存储过程调用(使用PreparedStatement)都会导致2次调用DB,第一次调用非常昂贵: exec sp_sproc_columns @procedure_name = SPROC_NAME,@ ODBCVer = 3(元数据调用) EXEC SPROC_NAME @ P0,@ P1,@ P2,@ P3(实际通话)
在阅读以下主题后,我们终于有了一些工作要做: Why is calling a stored procedure always preceded by a call to sp_sproc_columns?
即使我们使用JDBC而不是ADO.NET,这个问题看起来与我们的问题非常相似,因此我们认为值得尝试一下。
更改到位后,数据库中的跟踪会话确认第一次调用不再出现在日志中。
之前我们将Map作为参数传递。当我们切换到Map并指定正确的数据类型时,我们开始看到性能改进。
简而言之,如果驱动程序包含有关params的所有数据(实际上是元数据),则它不会发出元数据调用。
答案 1 :(得分:0)
发布此问题已经有一段时间了;但是,鉴于我正在处理此问题,我花了相当长的时间才弄清楚,因此我会留下我的答案。希望对别人有帮助。
简短答案::请勿在过程调用中使用命名参数。请改用有序参数。
长答案::使用命名参数时,JDBC驱动程序首先发出对“ sp_sproc_columns”过程的调用。驱动程序发出此调用以获取过程中参数的名称,并运行一些验证以检查名称是否正确。稍后,它将替换查询中的命名参数,并以正确的顺序放置它们。确定正确的顺序后,驱动程序将改为使用有序参数来调用该过程。