代码之家  ›  专栏  ›  技术社区  ›  Klaus Byskov Pedersen

SQL Server不区分大小写排序规则

  •  12
  • Klaus Byskov Pedersen  · 技术社区  · 15 年前

    在SQL Server中使用不区分大小写的排序规则有什么好处/缺点(从查询性能方面来说)?

    我有一个数据库,目前正在使用不区分大小写的排序规则,我不太喜欢它。我很想把它改成区分大小写的。更改排序规则时我应该注意什么?

    5 回复  |  直到 14 年前
        1
  •  5
  •   BradC    15 年前

    (我将此作为一个单独的答案添加,因为它与我的第一个答案有很大的不同。) 好的,找到一些实际的文档。这个 MS KB article 说那里 不同排序规则之间的性能差异,但不是您认为的那样。区别在于 SQL排序规则 (向后兼容,但不支持Unicode)和 Windows排序规则 (支持Unicode):

    一般来说,Windows和SQL排序规则之间的性能差异程度不会太大。只有当工作负载是CPU绑定的,而不是受I/O或网络速度的约束时,才会出现这种差异,并且这种CPU负担的大部分是由SQL Server中执行的字符串操作或比较的开销造成的。

    SQL和Windows排序都有区分大小写和不区分大小写的版本,所以听起来这不是主要的问题。

    丹优秀文章《战壕中的另一个好故事》 Collation Hell “:

    我继承了一个混合的排序环境,它的排序比我一方面所能指望的要多。不同的排序规则需要解决方法来避免“无法解决排序规则冲突”错误,并且这些解决方法会由于不可分析的表达式而导致性能下降。处理混合排序是一个真正的痛苦,所以我强烈建议您标准化一个排序,只有在仔细考虑后才偏离。

    他得出结论:

    我个人认为在选择正确的排序时甚至不应该考虑性能。我生活在collation hell中的一个原因是,我的前任选择了二进制排序,以帮助我们的高事务性OLTP系统获得每一点性能。除了前面的通配符表扫描搜索之外,我发现不同的排序没有可测量的性能差异。性能的真正关键是查询和索引调优,而不是排序规则。如果性能对您很重要,我建议您在根据性能期望选择排序规则之前,使用实际的应用程序查询执行性能测试。

    希望这有帮助。

        2
  •  6
  •   Damien_The_Unbeliever    15 年前

    如果更改数据库上的排序规则,则还必须单独更改每列上的排序规则-它们维护创建表时生效的排序规则设置。

    create database CollTest COLLATE Latin1_General_CI_AI
    go
    use CollTest
    go
    create table T1 (
        ID int not null,
        Val1 varchar(50) not null
    )
    go
    select name,collation_name from sys.columns where name='Val1'
    go
    alter database CollTest COLLATE Latin1_General_CS_AS
    go
    select name,collation_name from sys.columns where name='Val1'
    go
    

    结果:

    name collation_name
    ---- --------------
    Val1 Latin1_General_CI_AI
    
    name collation_name
    ---- --------------
    Val1 Latin1_General_CI_AI
    
        3
  •  5
  •   HLGEM    15 年前

    我想说,在生产数据库中更改为区分大小写的排序规则的最大缺点是,许多查询(如果不是大多数)都会失败,因为它们当前被设计为忽略大小写。

    我没有尝试在现有的数据库上更改排序规则,但我怀疑这样做也可能相当耗时。当这个过程也发生时,您可能必须完全锁定您的用户。不要尝试这个,除非你已经对dev进行了彻底的测试。

        4
  •  2
  •   BradC    14 年前

    我找不到任何证据来证实 结构合理 查询在区分大小写的数据库和不区分大小写的数据库上工作得更快(尽管我怀疑差异可以忽略不计),但我清楚一些事情:

    1. 如果你的业务需求没有要求,你就需要做很多额外的工作(这是hlgem和damien-the-unbeliever答案的关键)。
    2. 如果您的业务需求没有要求它,那么您将为许多可能的错误做准备。
    3. 在不区分大小写的数据库中,如果 敏感的 查找是必需的:

    类似的查询:

    ... WHERE UPPER(GivenName) = 'PETER'
    

    不会在givenname上使用索引。你可能会想:

    ... WHERE GivenName = 'PETER' COLLATE SQL_Latin1_General_CP1_CS_AS
    

    会更好,而且确实如此。但要获得最佳性能,您必须执行以下操作:

    ... WHERE GivenName = 'PETER' COLLATE SQL_Latin1_General_CP1_CS_AS
        AND GivenName LIKE 'PETER'
    

    (见 this article 详细信息)

        5
  •  1
  •   MartW    15 年前

    如果更改了数据库排序规则而不是服务器排序规则(结果是它们不匹配),那么在使用临时表时要当心。除非其create语句中另有规定,否则它们将使用服务器的默认排序规则,而不是数据库的默认排序规则,该排序规则可能导致联接或与数据库的列进行其他比较(假设它们也被更改为数据库的排序规则,正如Damien_the Unbeliever所暗示的那样)失败。

    推荐文章