代码之家  ›  专栏  ›  技术社区  ›  ercan

为什么SUBSTRING或LEFT使查询速度慢得多?

  •  3
  • ercan  · 技术社区  · 14 年前

    -- Query 1
    SELECT * 
    FROM bldb.dbo.blacklist l
    WHERE l.matchcode
        = dbo.fn_matchcode('12345','Sesame Street','1','Eddie','Bert')
    

    查询运行得非常快,因为matchcode列上有一个索引,并且 fn_matchcode

    把matchcode看作是地址和名称的压缩形式,这有助于我不受街道名称等拼写错误的影响。它由22个字符组成:地址13个字符,名称9个字符。当我想看看 芝麻街1号,12345

    -- Query 2
    SELECT * 
    FROM bldb.dbo.blacklist l
    WHERE LEFT(l.matchcode,13)
        = LEFT(dbo.fn_matchcode('12345','Sesame Street','1','Eddie','Bert'),13)
    

    运行时间非常长。。。

    相反,它运行得更快:

    -- Query 3
    SELECT * 
    FROM bldb.dbo.blacklist l
    WHERE LEFT(l.matchcode,13)
        = (SELECT LEFT(dbo.fn_matchcode('12345','Sesame Street','1','Eddie','Bert'),13))
    

    LEFT()

    编辑:

    到目前为止,答案声称这是因为索引没有被使用。然而,我仍然不清楚为什么会发生以下情况。

    -- Query 4
    SELECT * 
    FROM bldb.dbo.blacklist
    WHERE matchcode LIKE LEFT(dbo.fn_matchcode('12345','Sesame Street','1','Eddie','Bert'),13) + '%'
    

    fn\U匹配码

    fn\U匹配码 在查询中:

    -- Query 5
    SELECT * 
    FROM bldb.dbo.blacklist
    WHERE matchcode LIKE '12345SSMSTRT1%'
    

    需要几毫秒!你怎么解释?

    5 回复  |  直到 14 年前
        1
  •  3
  •   Martin Smith    14 年前

    在问题更新之后,您能否查看查询的两个执行计划#4和#5,并查看它是否对其中一个执行聚集索引扫描,对另一个执行非聚集索引搜索?我想知道是不是因为它知道编译时的文字统计信息,而不知道函数调用的统计信息。由于它不知道只会返回少数记录,因此它在避免进行大量书签查找方面犯了错误。

    SELECT * 
    FROM bldb.dbo.blacklist WITH (FORCESEEK)
    WHERE matchcode LIKE 
      LEFT(dbo.fn_matchcode('12345','Sesame Street','1','Eddie','Bert'),13) + '%'
    
        2
  •  1
  •   Martin Smith    14 年前

    我会用

    SELECT * 
    FROM bldb.dbo.blacklist l
    WHERE l.matchcode LIKE 
      LEFT(dbo.fn_matchcode('12345','Sesame Street','1','Eddie','Bert'),13) + '%'
    

    允许使用匹配代码上的索引。不过,这并不能回答你的问题,但评论时间太长了。

        3
  •  1
  •   HLGEM    14 年前

        4
  •  1
  •   OMG Ponies    14 年前

    这意味着,在where条件的右侧,计算每一行的值!

    不,您正在考虑相关的子查询-这不是。

        5
  •  0
  •   supercat    14 年前

    要使查询快速运行,必须为所查询的对象建立索引。如果要基于从一个或多个列计算的值进行查询,则需要有一个包含该计算结果的索引列。