查询执行时间是不是因大表的不同查询参数值而异?

Posted

技术标签:

【中文标题】查询执行时间是不是因大表的不同查询参数值而异?【英文标题】:Does query execution time differs based on different query param value with huge table?查询执行时间是否因大表的不同查询参数值而异? 【发布时间】:2019-02-26 14:38:25 【问题描述】:

我们正在使用 Spring Boot、SQL Server 和 Azure 云。

目标是在一个有 52 条记录的表中逐批更新 2000 条记录 百万行而不使用本机查询。

该表有一个外键,每个外键都有大量的行,并按外键值进行分区。

样本表,

seq |  id | value
-------------------
1   | A1  | v1  
2   | A1  | v2  
3   | B1  | v3
4   | B1  | v4

... 实际的查询是,

select * from sample where id=? and value in (?) 
2 parameter will have 2000 strings.

using Spring data JPA repository methods.

A1 有 10 万条记录。 B1 有 40 万条记录。

当我使用 A1 和 2000 个值执行查询时。提取需要 17 秒。 使用 B1 和另外 2000 个值(A1 没有)需要 70 秒才能从应用程序中获取。

但是当我在 SSM 中执行相同的查询时,只需要 3 秒。

是不是因为 B1 从 400K/52M 过滤而 A1 从 100K/52M 过滤?

连接字符串有,sendStringParametersAsUnicode=false; 并且两列也有索引。

为每一行尝试了 CriteriaUpdate,但结果相同 - 2K/100K/52M 需要 35 秒,2K/400K/52M 需要 2 分钟。所以放弃了它,现在尝试一下,一次获取所有内容并一次更新所有内容。无论如何,更新速度更快,只有获取需要时间。

注意: 我们没有对这个特定的过程使用 Spring Batch,因为将从 Flatfile 读取记录,并且必须在该表中更新文件中的每一行。因此有一个读取器从文件中读取行,处理器对 DTO 进行处理,并且写入器尝试执行此 update.chunk 大小 2000。

【问题讨论】:

Slow in the Application, Fast in SSMS? @LukaszSzozda 我已经阅读了那篇文章。在我的情况下,时间根据具有大容量的不同查询参数值而有所不同。时间会根据它过滤的数量而增加。我也在尝试使用那篇文章来解决这个问题。但无论如何都意味着需要帮助。 select * from sample where id=? and value in (?) OPTION (RECOMPILE) 【参考方案1】:

好的,它正在工作并且比以往更快。现在提取需要几毫秒。

我在属性文件中的 JDBC 连接字符串有sendStringParametersAsUnicode=false;

但它实际上是从没有它的 deployment.yaml 文件中挑选出来的。

sendStringParametersAsUnicode=false;

文档,

如果 sendStringParametersAsUnicode 属性设置为“true”,则字符串参数以 Unicode 格式发送到服务器。

如果 sendStringParametersAsUnicode 属性设置为“false”,则字符串参数以 ASCII/MBCS 等非 Unicode 格式而不是 Unicode 发送到服务器。

sendStringParametersAsUnicode 属性的默认值为“true”。

注意:仅当发送具有 CHAR、VARCHAR 或 LONGVARCHAR JDBC 类型的参数值时,才会检查 sendStringParametersAsUnicode 属性。新的 JDBC 4.0 国家字符方法,例如 SQLServerPreparedStatement 和 SQLServerCallableStatement 类的 setNString、setNCharacterStream 和 setNClob 方法,无论此属性的设置如何,始终以 Unicode 将其参数值发送到服务器。

谢谢。

【讨论】:

以上是关于查询执行时间是不是因大表的不同查询参数值而异?的主要内容,如果未能解决你的问题,请参考以下文章

与大表的内部联接减慢查询

SQL性能问题.现在表设计可以把一个大表按类型(各类型字段不相同)拆分成多个小表.拆分后比较方便.

mysql中两个大表之间的连接查询

优化大表查询执行 generate_series()

mysql 表很少,一个大表上的子查询执行缓慢

BigQuery 无法查询滞后的大表