【问题标题】:SQL Server :: implicit conversion of Data Type in query from Microsoft Access?SQL Server :: Microsoft Access 查询中数据类型的隐式转换?
【发布时间】:2020-10-09 14:12:45
【问题描述】:

几周以来,我一直在管理一个经常受到 Microsoft Access 应用程序攻击的 SQL Server 2019。

我发现了这个 Brent Ozar post(谢谢@Brent),我发现 Access 中的数据类型在 SQL Server 中是不一样的:

我知道improve performances 有很多方法,但我需要知道的是:数据类型在从 Access 转换为 SQL Server 时是否提交隐式转换?

例如,SQL Server 如何将 Access 中的 Short Text 解释为 bigintchar(10)datetimeoffsetnchar(10)varchar(50) 等...?

在我看来,它们都像是隐式转换,对吧?

【问题讨论】:

  • 如果您要问,例如,当 Access 执行 WHERE BigintColumn = '123456789123456' 之类的操作时会发生什么,那么 varchar 值 ('123456789123456') 将被隐式转换为 bigint,是的。当比较两种不同的数据类型时,具有较低数据类型优先级的列将(尝试)转换为另一个(具有较高数据类型优先级)的数据类型。
  • 一些隐式转换是way more expensive而不是其他的。
  • 谢谢@Larnu 和 Aron Bertrand。我相信逃避这一点的唯一方法是在 SQL Server 上创建存储过程并让 Access 触发它们。你怎么看?
  • 如果您要设置程序,那么唯一的隐式转换就是从访问提供的值到参数的数据类型。它肯定会导致WHERE 中的隐式转换,尤其是列中的转换(除非您已将参数声明为不正确的数据类型)。

标签: sql-server ms-access type-conversion database-performance implicit-conversion


【解决方案1】:

我厌恶地发现 Access 中的数据类型与 SQL Server 中的不同:

You find that FoxPro data types are different. 
You find that Excel sheets data types are different
You find that SharePoint lists and data types are different
(all of the above are Microsoft products).

You find that MySQL data types are different
You find that Oracle data types are different
And so on. So data types "are" often different.

结果? 您会发现,即使不是大多数数据系统,也确实必须使用一些不同的数据类型。因此,ODBC 或 oleDB,甚至现在的 jdbc 驱动程序都将处理从服务器到客户端软件所需的转换。这可能会导致某些数据类型根本不受支持。

当数据类型从 Access 转换到 SQL Server 时,它们是否提交隐式转换?

是的,你是对的。 实际上它是 ODBC 驱动程序。 SQL 服务器不“知道”客户端查询请求是否来自 Access、FoxPro、VB6、vb.net,甚至是一些花哨的 asp.net 网站。

在所有情况下,数据查询的速度和拉动速度都是相同的。

SQL 服务器不会突然决定 Access 中的某些查询或来自 asp.net 网站的某些 sql 查询运行得更慢还是更快。

ODBC 驱动程序(或现在很少使用的 oleDB 驱动程序)的数据类型转换(自动)在提取数据方面绝不会产生重大成本或开销。

所以,访问的速度,或者说一个asp.net网站拉一些数据是一样的。

因此,访问中的任何查询都不应比从 asp.net 或某些花哨的 c# 客户端程序发送的查询慢。它们都以相同的速度运行,并且数据类型转换是 ALL ODBC 或客户端软件用于提取此类数据的驱动程序的正常部分。

那么,如果我使用 Access、FoxPro、VB6、C# 或一些 asp.net 网站来连接 SQL 服务器并从 SQL 服务器提取数据?那么在所有这些情况下,与 .net 兼容的数据类型转换将由驱动程序和使用的连接堆栈发生。这种数据类型转换在性能方面确实没有任何重要因素。

那么,从 Access 或 .net 提交的查询?它们应该运行相同。但是,Access 具有(以及 .net 和大多数其他连接技术没有)的一个特性和能力是 Access 可以连接不同的连接对象。所以,我可以有一个本地表,一个链接到 Foxpro,另一个链接到 SQL 服务器。在 Access 中,您可以在这些不同的数据源表之间执行连接和 sql 查询。例如,在 .net 中,查询仅限于一个连接对象。

但是,这也意味着任何尝试在两个数据源表(甚至是同一个数据库)之间进行关系连接的查询都可能发生在客户端(因为 Access 可以做到这一点,而大多数系统都缺乏这种能力)。因此,在某些情况下,从 Access 中选择查询或说 asp.net 提取数据的速度差异很小(如果有的话)?

当涉及到关系联接时,Access 会导致关系联接和工作发生在客户端而不是服务器端。在这些情况下,您可以通过多种方法强制查询(和连接)发生在服务器端。在这些情况下,这样的查询会运行得很慢。

最佳选择:

使用/创建视图并从 Access 客户端链接到该视图。这是最好的选择。原因是您获得与传递查询相同的性能,并且获得与存储过程相同的性能。但是,没有代码或工作可以做到这一点。完成后,您再次发现 Access 客户端中的查询拉取速度与任何其他客户端软件(.net、asp.net、c# 等)相同。

再一次,从性能的角度来看,所涉及的驱动程序对数据类型转换的任何考虑都是一个模拟题。

您可以考虑使用传递查询来代替链接视图的少量工作和工作。这当然又是从 Access 客户端发送的原始 T-SQL 语句,并且数据类型问题也非常有争议,因为这是发送到 sql server 的 t-sql 语法代码,因此它的 t-sql 采用 sql 语句并从 ASCII(好吧,uni-code)字符串进行数据类型转换,并将该字符串转换为数字、日期类型等。但是,对于您编写的任何具有以此类表示的值的 sql 语句,这种数据转换再次发生字符串。

那么是 .net、FoxPro、Access、asp.net 客户端软件吗?他们都将并且必须在数据和客户端软件之间进行数据转换类型。例如,.net 有几种数据类型,您可以在代码中定义 Access、FoxPro 甚至 VB6(甚至 c++)都没有。因此,每个客户端系统都在不断地从该软件中的本机变量和数据类型转换为 sql server 上使用的数据类型。

因此,所有客户端软件都会发生这种数据转换,并且这种转换在 Access 中不再是性能因素,然后在 c++ 甚至汇编程序中编写代码。所有这些系统在拉取发送到 sql server 的查询时的速度都是一样的。

【讨论】:

  • 感谢@Albert 抽出宝贵时间撰写此回复。愿你的努力帮助整个社区。它绝对帮助了我。
  • 天哪,这是您的帖子和问题的所有权。查看我的编辑,我已经删除了其中的任何居高临下的语气。我向你致敬——这是你真正的荣幸。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 2017-04-15
  • 1970-01-01
  • 2016-12-27
  • 2016-04-10
  • 2012-06-26
相关资源
最近更新 更多