gpt4 book ai didi

sql-server - 表变量列中的 nvarchar(max) 与 nvarchar(n)

转载 作者:行者123 更新时间:2023-12-03 01:45:54 25 4
gpt4 key购买 nike

在最终向用户呈现结果集之前,我对表变量进行了大量工作。例如,我可能会从许多不同的表中提取全部列,如下所示:

DECLARE @tmp TABLE
(
ID int,
username nvarchar(50), -- data taken from tbl_Users
site nvarchar(50), -- data taken from tbl_Sites
region nvarchar(100), -- data taken from tbl_Regions
currency nvarchar(5) -- data taken from tbl_Currencies
)

我花了很多时间浏览对象资源管理器以确保列的数据长度正确(与原始表匹配)。有时,如果我更改表架构但不更新所有过程,我可能会遇到截断错误。

采取懒惰的方法并这样做是否有任何问题:

DECLARE @tmp TABLE
(
ID int,
username nvarchar(max),
site nvarchar(max),
region nvarchar(max),
currency nvarchar(max)
)

nvarchar(max) 实际上会使用更多内存还是根据数据大小分配的内存?还有其他问题吗?

请注意,我知道可以使用第三方工具跳转到定义,但这不是我要问的。

更新

重复的问题有值(value),但恕我直言,问题并不相同。副本围绕实际表的设计,而不是表变量。然而,答案有一些优点,即:

  • 在数据长度超过 8000 个之前,nvarchar(max) 与 nvarchar(8000) 在资源使用方面没有区别
  • 业务逻辑层依赖于结构和有意义的数据,因此指定与原始数据相匹配的列大小可以提供值(value)

从这个意义上说,在表变量中使用 nvarchar(max) 代替 nvarchar(n) 似乎没问题,但它具有可靠性和某些环境中的性能风险。如果您认为应该删除此内容,那么很公平(但请停止争论,我感谢所有意见!)

最佳答案

我想不出有任何理由在表变量中使用 nvarchar(max) 会有任何与在表( the downsides of which are explained in this question )中使用 nvarchar(max) 不同的陷阱,除了由于首先,表变量和临时/永久表之间的差异(例如糟糕的统计数据、没有二级索引等)。 Martin Smith draws a great comparison between table variables and temp tables here .

您仍然需要担心某些问题,例如,如果您使用经典的 ASP/ADO 等古老技术,您可能会发现必须最后列出 MAX 列才能确保结果准确。 I explained this here back in 2000, before MAX types were introduced ;但他们在那些旧的提供程序中存在与 TEXT/NTEXT 相同的问题。您不太可能使用该技术,但我想我会提到它以防万一。

不过,我建议您在编写代码时接受并编写正确的类型。它们很容易从元数据中派生(例如 sys.columns 或右键单击表并说出脚本 > 创建到 > 剪贴板),这样做可以防止出现任何问题(例如 the one @JC. mentioned above 有关长度不匹配,可能导致溢出/截断)。

此外,正如我之前暗示的那样,如果您有大量行(感谢@Stuart),您应该考虑使用 #temp 表。我仍然认为,无论你选择什么,都应该有明确的定义。在这种情况下,使用 MAX 处理所有事情的唯一好处是,它可以让您变得懒惰,同时让您面临很大的风险。您编写代码一次,但您的用户运行它无数次。多花几分钟来使数据类型正确,即使这意味着如果架构发生更改,您必须在稍后更正两次。

至于nvarchar(max)的内存使用情况,是的,这可能会改变您的性能。 See this blog post for some evidence 。部分相关片段,以及我的拼写/语法更正:

So if you are sure that the length of your nvarchar column will be less than 8000, then do not define the column as nvarchar(max) but rather define it as nvarchar(fixedlength) wherever possible. The main advantages I see for using fixed length are:

Memory grant could be a big issue where the server is already memory starved. As expected row size is more the optimizer will estimate more memory grant and this value will be much higher than actually required and this would be a waste of a resource as precious as memory. If you have couple of queries which are using nvarchar(max) column and sorting is needed then server might have memory related issues. This could be a big perf issue.

他列出的其他优点与索引有关。无论如何,这不是表变量的问题,因为您无法创建二级索引(在 SQL Server 2014 之前)。

但是,无论您从哪种类型的表结构中提取数据(临时表、表变量、永久表等),这个潜在的问题实际上都没有什么不同。

关于sql-server - 表变量列中的 nvarchar(max) 与 nvarchar(n),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21141598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com