【问题标题】:Affecting performance with SQL Collation使用 SQL 排序规则影响性能
【发布时间】:2011-09-02 23:50:12
【问题描述】:

我只想检查几件事:

Q1) Latin1_General_CI_AS 不区分大小写,区分重音:即SQL 会将以下内容视为相等 - “hello”和“HELLO”

我经常使用 LINQ:

db.Where(v => v.Email == "some email".ToLower())

Q2) 假设我对 Q1 的理解是正确的,我是否只是在浪费处理时间在我的查询中调用 ToLower()?

Q3) 有人知道使用 Latin1_General_bin 是否会比使用 Latin1_General_CI_AS 提高性能吗?即已经在博客等上进行了性能测试(在我写这篇文章时想到了这一点,所以还没看我自己)

【问题讨论】:

  • 排序规则不仅会影响这些查找,还会影响排序顺序。您的查询是否曾经在这些列上使用过order by?如果是这样,您期望这些语义是什么?
  • 一般不会。老实说,这取决于查询的性质。我是否正确地说大小写/重音敏感性是影响排序顺序的事情?
  • Latin1_General_bin 会将A,B,a,b(大写优先)和Latin1_General_CI_AS 排序为A,a,B,b。我不记得有关排序规则如何影响排序的所有血腥细节。
  • Per this other question's answer“微软优化了ToUpperInvariant(),而不是ToUpper()。不同之处在于不变量对文化更友好......”

标签: sql sql-server linq performance collation


【解决方案1】:

一般而言,SQL 比较不区分大小写。
但是也有例外,例如在 MySQL 中,如果您使用 binary varchar 比较将区分大小写。

因此,您的 ToLower 可能不会完全浪费时间。

Latin1_General_bin 区分大小写。
Latin1_General_CI_AS 不是。

在数据库中进行区分大小写的比较会更快,但如果要将“some email”与“Some email”匹配,则需要付出代价,您必须将其转换为小写,从而失去所有速度增益。
我还没有计时,但我认为这不值得麻烦。
我建议在微优化之前巧妙地使用索引和查询。

-- 过早的优化是万恶之源,Donald Knuth。

【讨论】:

    【解决方案2】:

    真实例子的表现: 表 Adres 包含 320K 行数据。当我们有电子邮件时,我们需要 Adres.Id(如您的示例中)。

    数据库(和表 Adres)排序规则是 SQL_Latin1_General_CP1_CI_AS

    为了性能优化,在Email列(包括Adres.Id列)上创建了非聚集索引

    查询看起来像:

    SELECT  Adres.ID,Email FROM  csc.Adres WHERE EMAIL ='23LMDLh6N@f8CyB7vPL.r4L'
    
    SELECT  Adres.ID,Email FROM  csc.Adres WHERE EMAIL='23LMDLh6N@F8CyB7vPL.r4L' COLLATE Latin1_General_bin
    

    每个查询返回 1 行

    结果:

    在第二种情况下,SQL Server 似乎没有将查询识别为 SARG。为什么?让我们看看细节。 第一种情况:

     ScalarOperator ScalarString="CONVERT_IMPLICIT(nvarchar(4000),[@1],0)
    

    第二个:

    ScalarOperator ScalarString="CONVERT_IMPLICIT(nvarchar(80),[CSCENTRUMTest].[csc].[Adres].[Email],0)=CONVERT_IMPLICIT(nvarchar(4000),CONVERT(varchar(8000),[@1],0),0)">
    

    所以在第二种情况下,电子邮件被转换为所需的排序规则。这种情况不是 SARG,而是执行了索引扫描。

    如果查询不能被识别为 SARG(例如LIKE '%some email%)',则计划相同。

    假设:如果您的查询可以被识别为 SARG 并且您有适当的索引,则首选无排序规则(最好在客户端/服务端进行排序规则对话)。

    您可以在不同的性能调优书籍/文章中找到 SARG 信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-28
      • 2017-02-12
      • 1970-01-01
      • 2019-03-06
      • 2012-06-08
      • 1970-01-01
      • 2018-04-27
      相关资源
      最近更新 更多