shs*_*mer 9 java connection-string sql-server-2005 jdbc
我有一个java程序,它对sql server数据库运行一堆查询.第一个是对视图进行查询,返回大约750k条记录.我可以通过sql server management studio运行查询,并在大约30秒内得到结果.但是,我昨晚启动了该计划.当我今天早上检查它时,这个查询仍然没有将结果返回到java程序,大约15个小时后.
我可以访问数据库来执行我想要的任何操作,但我真的不确定如何开始调试它.应该怎么做才能找出造成这种情况的原因?我不是一个dba,并且我对sql server工具集并不熟悉,所以你可以给我更多关于如何做你可能建议的细节,我将不胜感激.
继承人的代码
stmt = connection.createStatement();
clientFeedRS = stmt.executeQuery(StringBuffer.toString());
Run Code Online (Sandbox Code Playgroud)
EDIT1:
好吧已经有一段时间了,而且这种情况有所不同,但这个问题又回来了.我考虑从jdbc驱动程序v 1.2升级到2.0,但是我们仍然坚持使用jdk 1.4,而v 2.0需要jdk 1.5,所以这是一个非首发.现在我正在查看我的连接字符串属性.我看到2可能有用.
SelectMethod=cursor|direct
responseBuffering=adaptive|full
Run Code Online (Sandbox Code Playgroud)
目前,由于延迟问题,我使用cursor作为selectMethod运行,并且responseBuffering的默认值已满.改变这些属性可能会有所帮助吗?如果是这样,那么理想的设置是什么?我在想,根据我在网上找到的内容,使用直接选择方法和自适应响应缓冲可能会解决我的问题.有什么想法吗?
EDIT2:
我是否结束了这两个连接字符串参数的更改,使用默认的select方法(直接)并将responseBuffering指定为自适应.这最终对我来说是最好的,并减轻了我看到的延迟问题.感谢所有的帮助.
Kho*_*opa 22
我有类似的问题,一个非常简单的请求(SELECT.FROM.WHERE =.)在Java中使用jdbc连接时需要10秒才能返回单行,而在sqlshell中只需0.01s.无论我使用官方MS SQL驱动程序还是JTDS驱动程序,问题都是一样的.
解决方案是在jdbc url中设置此属性: sendStringParametersAsUnicode = false
完整示例如果您使用的是MS SQL官方驱动程序:jdbc:sqlserver:// yourserver; instanceName = yourInstance; databaseName = yourDBName; sendStringParametersAsUnicode = false;
如果在这里使用不同的jdbc驱动程序和更多关于此问题的详细信息的说明:http://emransharif.blogspot.fr/2011/07/performance-issues-with-jdbc-drivers.html
SQL Server将支持Unicode的数据类型与仅支持ASCII的数据类型区分开来.例如,支持Unicode的字符数据类型是nchar,nvarchar,longnvarchar,因为它们的ASCII计数器部分分别是char,varchar和longvarchar.默认情况下,所有Microsoft的JDBC驱动程序都将Unicode格式的字符串发送到SQL Server,而不管SQL Server中定义的相应列的数据类型是否支持Unicode.在列的数据类型支持Unicode的情况下,一切都很顺利.但是,如果列的数据类型不支持Unicode,则会在数据提取期间出现严重的性能问题.SQL Server尝试在执行比较之前将表中的非unicode数据类型转换为unicode数据类型.此外,如果非unicode列上存在索引,则将忽略该索引.这最终会在数据提取期间导致整个表扫描,从而大大减慢搜索查询的速度.
在我的情况下,我在搜索的表中有30M +记录.申请完成申请的时间从10秒以上到申请财产后大约0.01秒.
希望这会对某人有所帮助!
看来这可能不适用于您的特定情况,但我想为搜索此问题的人提供另一种可能的解释.
我只是遇到了类似的问题,在SQL Server中直接执行查询需要1分钟,而同一查询通过java编写的statemnent需要5分钟.我追踪到它是作为准备好的声明完成的事实.
在SQL Server中直接执行查询时,您将为其提供非参数化查询,在该查询中,它在优化时知道所有搜索条件.在我的情况下,我的搜索条件包括一个日期范围,SQL服务器能够查看它,决定"日期范围是巨大的,让我们不使用日期索引",然后它选择了更好的东西.
当我通过java预处理语句执行相同的查询时,在SQL Server优化查询时,您还没有提供任何参数值,因此它必须猜测要使用哪个索引.在我的日期范围的情况下,如果它优化了小范围并且我给它一个大范围,它将执行比它可能更慢.同样地,如果它针对大范围进行优化并且我给它一个小范围,那么它将再次执行得比它慢.
为了证明这确实是问题,作为一个实验,我尝试给出了关于使用SQL Server的"OPTIMIZE FOR"选项进行优化的提示.当我告诉它使用一个很小的日期范围时,我的java查询(实际上有一个很宽的日期范围)实际上花了两倍的时间(10分钟,而不是之前的5分钟,而不是SQL Server中的1分钟) ).当我告诉它我要确定的确切日期时,java预处理语句的执行时间是相同的.
所以我的解决方案是将确切日期硬编码到查询中.这对我有用,因为这只是一次性的陈述.PreparedStatement不打算重用,而只是参数化值以避免SQL注入.由于这些日期来自java.sql.Date对象,因此我不必担心包含注入代码的日期值.
但是,对于需要重用DOES的声明,对日期进行硬编码是行不通的.也许更好的选择是创建针对不同日期范围优化的多个预准备语句(一天一个,一个一个月,一个月一个,一年一个,十年一个......或者你可能只需要2或3个选项...我不知道)然后对于每个查询,执行一个预准备语句,其时间范围最符合实际查询中的范围.
当然,这只适用于日期范围均匀分布的情况.如果80%的记录是去年的,而20%的记录分布在过去的10年中,那么做"基于范围大小的多个查询"的事情可能不是最好的.您必须根据特定范围或某些内容优化查询.你需要通过试验找出错误.
确保您的 JDBC 驱动程序配置为使用直接连接而不是基于光标的连接。如果您不确定,您可以发布您的 JDBC 连接 URL。
确保您使用的是只进、只读的结果集(如果您没有设置它,则这是默认值)。
并确保您使用的是更新的 JDBC 驱动程序。
如果所有这些都不起作用,那么您应该查看 sql profiler 并尝试在 jdbc 驱动程序执行语句时捕获 sql 查询,然后在管理工作室中运行该语句,看看是否有区别。
此外,由于您要提取如此多的数据,您应该尝试确保 JVM 上没有任何内存/垃圾收集速度减慢(尽管在这种情况下并不能真正解释时间差异)。
| 归档时间: |
|
| 查看次数: |
20988 次 |
| 最近记录: |