【问题标题】:SQL Collation Issue on JOIN clause -- EXTREMELY slow runtimeJOIN 子句上的 SQL 排序规则问题——运行时极慢
【发布时间】:2018-09-20 06:27:48
【问题描述】:

我正在尝试在查询中连接来自不同数据库的两个表。它们有不同的排序规则类型。主数据库具有排序规则:SQL_Latin1_General_CP1_CS_AS

我要加入的数据库具有排序规则:SQL_Latin1_General_CP1_CI_AS

当我尝试在没有排序规则的情况下运行时出现此错误(显然):

无法解决之间的排序规则冲突 “SQL_Latin1_General_CP1_CS_AS”和“SQL_Latin1_General_CP1_CI_AS”在 等于运算。

我对整理不熟悉,所以我不知道该怎么办。如果我从查询中删除第二个数据库的各个方面,它会立即运行。一旦我开始使用连接,查询就会运行一个小时以上,但没有任何结果。

如果您需要更多上下文,请告诉我。

【问题讨论】:

  • 你能显示你正在使用的两个不同的查询吗?
  • 您是否要以区分大小写的方式加入?
  • 更改列的排序规则将使查询不可搜索;因此,您拥有的任何索引都将在该列上被忽略。这很可能是您的查询变得如此缓慢的原因。
  • @Larnu 在做了一点谷歌搜索之后,这就是我发现的。有没有解决这个问题的好方法?不幸的是,我无法真正改变表格。
  • @EzequielLópezPetrucci 我不在乎大小写,因为它的价值!

标签: sql sql-server sql-server-2012 collation collate


【解决方案1】:

正如 cmets 中所讨论的,在查询中更改列的排序规则会使语句不可 SARGable。这就是为什么您会看到性能显着下降的原因,因为您无法使用索引。

如果您需要在 2 个数据库上保持不同的排序规则,那么一种方法是添加一个 PERSISTED 计算列。然后,您可以改为在该列上添加索引。这将保持 SARGability。

如果您要保留非大小写敏感,那么您需要在区分大小写的数据库中创建计算列。我不知道您的列的名称,但是您对计算列的声明将类似于:

ALTER TABLE YourTable ADD YourColumn_CI AS YourColumn COLLATE SQL_Latin1_General_CP1_CI_AS PERSISTED;

然后您也可以在该新列上创建索引,并且您应该获得性能优势。

编辑:作为一个非常简单的示例索引:

CREATE INDEX YourColumn_CI_IX ON YourTable (YourColumn_CI ASC);

【讨论】:

  • 我想我不明白如何在不更改表的情况下在查询中创建索引。我需要使用临时表吗?
  • 不,根本不需要使用临时表。你不明白我的回答的哪一部分?但是,索引并不是可以简单地在 SO 的答案中教授的东西。或者是 cmets。
猜你喜欢
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
相关资源
最近更新 更多