gpt4 book ai didi

sql - 将 char 数据存储为 nvarchar 有什么危害? (而且不一致)

转载 作者:行者123 更新时间:2023-12-02 08:20:04 25 4
gpt4 key购买 nike

我正在开发一个系统,我们有许多内部生成的引用代码。这些代码都可以使用一个简单的、一个字节一个字符的集合来表示。此外,代码始终具有固定长度。

但是,在不同的数据库和表中,代码以 varcharnvarchar 的混合形式存储。我如何找到这种做法的不利成本?当需要从 varchar 连接到 nvarchar 或相反时,我可以看到查询计划的实际变化,但不知道如何将其表示为业务成本。

我的问题有很多部分:

  • 我如何才能收集一些具体的证据来向当权者展示我们当前设计的问题?
  • 危害是否大到我应该首先关注的程度?
  • 对固定长度数据使用可变长度字符字段是否会产生任何额外成本?
    • 如果是这样,该费用何时适用?仅当 SQL 写入磁盘时?在所有连接上?等等?

到目前为止,我放在一起的最简单的示例显示了查询计划的差异,但当然,由于它非常小,每个查询成本可以忽略不计,并且总体运行时间不到一秒:

declare @Source1 table(Field1 char(4));
insert into @Source1 values ('1234'),('2345');
declare @Source2 table(Field1 varchar(4));
insert into @Source2 values ('1234'),('2345');
declare @Source3 table(Field1 nvarchar(4));
insert into @Source3 values (N'1234'),(N'2345');

declare @Consumer1 table(Field1 char(4), FilterField int);
insert into @Consumer1 values ('1234', 5);
declare @Consumer2 table(Field1 varchar(4), FilterField int);
insert into @Consumer2 values ('1234', 5);
declare @Consumer3 table(Field1 nvarchar(4), FilterField int);
insert into @Consumer3 values (N'1234', 5);

select * from @Consumer1 c inner join @Source1 s on c.Field1 = s.Field1 where c.FilterField = 5;
select * from @Consumer1 c inner join @Source2 s on c.Field1 = s.Field1 where c.FilterField = 5;
select * from @Consumer1 c inner join @Source3 s on c.Field1 = s.Field1 where c.FilterField = 5;

select * from @Consumer2 c inner join @Source1 s on c.Field1 = s.Field1 where c.FilterField = 5;
select * from @Consumer2 c inner join @Source2 s on c.Field1 = s.Field1 where c.FilterField = 5;
select * from @Consumer2 c inner join @Source3 s on c.Field1 = s.Field1 where c.FilterField = 5;

select * from @Consumer3 c inner join @Source1 s on c.Field1 = s.Field1 where c.FilterField = 5;
select * from @Consumer3 c inner join @Source2 s on c.Field1 = s.Field1 where c.FilterField = 5;
select * from @Consumer3 c inner join @Source3 s on c.Field1 = s.Field1 where c.FilterField = 5;

有关其他信息,我们在开发和测试中使用 SQL Server 2014,在实际环境中使用 2008。我不希望在这个用例中有任何差异,但我想我会问我是否也需要为此考虑一些事情?

最佳答案

nvarchar 通常会使用两倍于 varchar 的空间。

如果您正在使用页面或行压缩(在这种情况下您会使用 Unicode 压缩)或双字节排序规则(在这种情况下,对于某些字符,varchar 每个字符也可以占用两个字节)。

主要问题是 nvarcharvarchar 具有更高的数据类型优先级,因此如果加入两者,则 varchar 端将需要隐式转换为 nvarchar 防止或至少阻碍该侧的索引使用。

(SQL Server 是否仍然可以管理 dynamic seek 取决于排序规则,尽管存在隐式转换,因此它可能不会完全排除嵌套循环连接的索引使用,但我怀疑您是否可以在两个上进行合并连接没有中间排序的两种不同数据类型的索引)

关于sql - 将 char 数据存储为 nvarchar 有什么危害? (而且不一致),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38058272/

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