草庐IT

java - 存储过程通过 Java 运行比直接在数据库上运行慢 30%

coder 2024-03-04 原文

我正在使用 Java 1.6、JTDS 1.2.2(也只是尝试了 1.2.4 无济于事)和 SQL Server 2005 来创建 CallableStatement 来运行存储过程(不带参数)。我看到运行相同存储过程的 Java 包装器比使用 SQL Server Management Studio 慢 30%。我运行了 MS SQL 分析器,两个进程之间的 I/O 几乎没有区别,所以我认为这与查询计划缓存无关。

存储过程不接受任何参数,也不返回任何数据。它使用服务器端游标来计算填充表所需的值。

我看不出从 Java 调用存储过程应该如何增加 30% 的开销,当然它只是一个通往数据库的管道,SQL 被发送下来,然后数据库执行它......数据库是否可以提供 Java应用不同的查询计划?

我已经发布到两个 the MSDN forums ,以及 sourceforge JTDS 论坛(主题:“在 JTDS 中存储的 proc 比直接在 DB 中慢”)我想知道是否有人对为什么会发生这种情况有任何建议?

提前致谢,

-詹姆士

(注意不要害怕,一旦我找到解决方案,我会在这里整理我在其他论坛中得到的任何答案)

Java代码片段:

sLogger.info("Preparing call...");
stmt = mCon.prepareCall("SP_WB200_POPULATE_TABLE_limited_rows");
sLogger.info("Call prepared.  Executing procedure...");
stmt.executeQuery();
sLogger.info("Procedure complete.");

我已经运行了 sql profiler,并发现了以下内容:

Java应用程序:
CPU:466,514 读取:142,478,387 写入:284,078 持续时间:983,796

安全管理系统:
CPU:466,973 读取:142,440,401 写入:280,244 持续时间:769,851

(在分析之前运行 DBCC DROPCLEANBUFFERS,并且都产生正确的行数)

所以我的结论是它们都执行相同的读取和写入,只是它们执行的方式不同,你们怎么看?

事实证明,不同客户端的查询计划有显着差异(Java 客户端在插入期间更新索引,而不是在更快的 SQL 客户端中,而且,它执行连接的方式也不同(嵌套循环 Vs.收集流,嵌套循环与索引扫描,啊!))。为什么会这样,我还不知道(我会在深入了解后重新发布)

结语

我无法让它正常工作。我尝试在 Java 和 Mgmt studio 客户端之间均质化连接属性( arithabortansi_nulls 等)。最终这两个不同的客户端具有非常相似的查询/执行计划(但仍然具有不同的实际计划 ID)。我将我发现的摘要发布到 the MSDN SQL Server forums因为我发现不仅 JDBC 客户端和管理工作室之间的性能不同,而且 Microsoft 自己的命令行客户端 SQLCMD 之间的性能也不同,所以我还检查了一些更激进的东西,例如网络流量,或者将存储的 proc 包装在另一个存储的 proc 中,只是为了咧嘴笑。

我有一种感觉,问题出在游标执行方式的某个地方,它以某种方式导致 Java 进程被挂起,但是为什么当没有其他任何东西在运行时,不同的客户端应该产生这种不同的锁定/等待行为并且同样的执行计划正在运行有点超出我的技能(我不是 DBA!)。

结果,我决定 4 天足以让任何人浪费时间在这样的事情上,所以我会勉强围绕它编码(如果我说实话,存储过程需要重新编码以增加增量而不是重新编码) - 无论如何每周计算所有数据),并将其归结为经验。我将问题悬而未决,非常感谢所有将他们的帽子放在戒指上的人,这一切都很有用,如果有人提出进一步的建议,我很想听听更多的选择……如果有人找到了这篇文章是在他们自己的环境中看到这种行为的结果,然后希望这里有一些指示,您可以自己尝试,并希望比我们更深入地了解。

我现在准备好过周末了!

-詹姆士

最佳答案

您可以附加事件探查器和监视器 SQL:BatchCompletedSP:Completed ,过滤器的持续时间 > 1000。从 Java 客户端和 SSMS 运行该过程。比较两个事件的读取和写入(Java 与 SSMS)。它们有显着不同吗?这将表明相当不同的执行路径或计划,具有显着的 I/O 差异。

也 try catch Showplan XML两者的事件并比较计划(将事件另存为 .sqlplan 文件,在 SSMS 中打开以方便分析)。他们有类似的计划吗?估计与实际(行、倒带、重新绑定(bind))之间是否存在巨大差异?它们的并行度是否相同?这些计划也可以从 sys.dm_exec_requests 中检索。看法。

是否引发了任何警告事件,例如 Missing Column Statistics , Sort Warnings , Hash Warning , Execution Warnings , Blocked Process ?

关键是您可以使用一整套调查工具。一旦找到差异的根本原因,就可以追溯到 Java 环境设置与 SSMS 环境 (ADO.Net SqlClient) 之间的差异。默认事务隔离级别、ANSI 设置等。

关于java - 存储过程通过 Java 运行比直接在数据库上运行慢 30%,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1790645/

有关java - 存储过程通过 Java 运行比直接在数据库上运行慢 30%的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  4. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  5. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  6. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  7. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  10. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

随机推荐