[英]Diagnose slow JDBC select statements against SQL Server running in a Hyper-V VM
我们刚刚构建了一个新的 Hyper-V 虚拟机来托管 Java 应用程序和 Microsoft SQL Server。 从 Java JDBC 应用程序运行 SQL 选择查询时,我们遇到了来自数据库的极其缓慢的响应。 从 SQL Server Management Studio 运行时,相同的查询会快速执行。
我们在裸机和 VMware 虚拟机上运行相同的 Java 应用程序和 SQL Server 数据库,没有任何性能问题。
我们的问题:
示例查询:
select * from view1 where app_id in (
select app_id from app_table where app_id % 1000 = 0)
order by app_id
响应时间:
Hyper-V 虚拟机
app_table 表只有两列。
create table app_table (
app_id [numeric](18,0) not null,
col_2 [varchar] (75)
)
app_view 视图也很简单。
create view app_view as select app_id from app_table
我们已经尝试了 Java 应用程序、JDBC 驱动程序和 SQL Server 的各种组合。
应用:
JDBC 驱动程序:
SQL Server 版本:
Java 版本:8_241
我不确定报告 SQL 分析结果的最佳方式,因此我将总结 SQL Profiler 报告的内容。 SSMS 客户端在 23 秒内执行视图查询。 JDBC 客户端用了 100 多秒的时间,查询在完成之前被取消。
SQL:BatchStarting "select * from app_view where ..." 2020-02-26 20:04:22
<一堆重复的东西>
审核登录/注销
RPC:已完成“exec sp_reset_connection”
BatchStarting/Completed "SET TRANSACTION ISOLATION LEVEL READ..."
</ 结束一堆重复的东西 > **SQL:BatchCompleted "select * from app_view where ..." 2020-02-26 20:04:45
SQL:BatchStarting "select * from app_view where ..." 2020-02-26 19:55:39
<一堆重复的东西>
审核登录/注销
RPC:已完成“exec sp_reset_connection”
BatchStarting/Completed "SET TRANSACTION ISOLATION LEVEL READ..."
</结束一堆重复的东西>
查询在 19:57:26 取消
我在 SSMS 和 JDBC 客户端中分析了更简单的查询,“从 app_table a 中选择前 5000 个 a.app_id”。 令人惊讶的是,两者都执行得很快,不到 1 秒。
SQL:BatchStarting "top 5000 a.app_id from app_table a" 2020-02-27 10:27:55.740
SQL:BatchCompleted "来自 app_table a 的前 5000 个 a.app_id" 2020-02-27 10:27:55.810
SQL:BatchStarting "top 5000 a.app_id from app_table a" 2020-02-27 10:25:45.063
SQL:BatchCompleted "来自 app_table a 的前 5000 个 a.app_id" 2020-02-27 10:25:45.843
首先,让我们看看问题实际上是 SQL Server、应用程序还是其他问题。 打开 SQL Profiler 并开始跟踪。
在跟踪运行的情况下,执行以下查询:
SELECT TOP 5000 a.app_id FROM dbo.app_table a;
(运行这个 SSMS)SELECT TOP 5000 a.app_id FROM dbo.app_table a;
(在您的应用程序/JDBC 客户端中运行此程序) (为了彻底,您可以针对您的观点重复上面的SELECT
语句。)
停止跟踪并记下相应应用程序的执行时间(持续时间)。
好的,所以我们得到了这些结果。
编辑:
简短的回答这个问题:客户端不应该的问题那么多(即:不应该有SSMS与.NET与JDBC等之间的差异是很大的),至于的Hyper-V对于裸-metal,裸机获胜(假设您的磁盘已虚拟化),原因显而易见。 您可以在 VM 中使用 DiskSpd ( https://aka.ms/diskspd ) 与类似规范的裸机环境运行一些 I/O 测试来证明这一点。
但是- 我不相信这些因素中的任何一个是问题所在。 根据您的跟踪结果,两个客户端在基表上都表现良好。 两个客户端对视图的表现都相对较差(Java 客户端比 SSMS 差)。 所以,我仍然建议,至少:
在 SSMS 中检查底层表上的索引碎片(右键单击表下的索引“文件夹”,单击“全部重建”,查看对话框中的数字。)甚至 PK 索引也可能变得碎片化,这会导致性能下降变得不稳定。
尝试不同版本的原始查询,例如:
SELECT * FROM dbo.app_view 其中 app_id % 1000 = 0
(没有 SELECT ...WHERE IN ... )
最后,实际视图的输出中有多少列? (如果视图非常宽,由于网络流量以及数据的客户端呈现,它可能会对客户端性能产生负面影响。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.