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

为什么这个SQL语句非常慢?

  •  8
  • Muxa  · 技术社区  · 15 年前

    我有一个大约有100万条记录的表(运行SQL Server 2008 Web)。我有一个搜索程序,它试图匹配产品代码和产品描述。 但在某些情况下,速度非常慢。以下是(减少)SQL语句:

    WITH AllProducts AS (
      SELECT       p.*, Row_Number() OVER (ORDER BY ProductId) AS RowNumber
      FROM        Product AS p 
        WHERE p.IsEnabled=1 AND
        (
          p.BaseSku = 'KPK-3020QWC-C' -- this on its own is fast
          OR
          CONTAINS(p.FreeTextStrings, '"KPK-3020QWC*"') -- and this on its own is fast, but not both
        )
    ) SELECT * FROM AllProducts        
      WHERE RowNumber BETWEEN 1 AND 20;
    

    注意,如果我只是在[P.basesku='kpk-3020qwc-c']或[contains(P.FreeTextStrings,'kpk-3020qwc*“')]上单独(但不是同时)比较它的即时性。如果我把它们放在一起比较的话,会花费很多时间(几分钟),并且只返回一行。

    IsEnabled和Basesku被索引,FreeTextStrings被FTS索引。

    我记得这以前很管用。

    有人能对这件事有所了解并提出一些解决办法吗?

    执行计划文件在此处可用: http://wiki.webgear.co.nz/GetFile.aspx?File=Temp%5cSearch%20Test.sqlplan.zip

    3 回复  |  直到 12 年前
        1
  •  10
  •   Eric    15 年前

    or 在SQL Server上速度非常慢。至少可以说,这很让人恼火。

    尝试将其拆分为两个查询 union :

    WITH AllProducts AS (
      select *, Row_Number() OVER (ORDER BY ProductId) AS RowNumber
      from (
      SELECT       p.*
      FROM        Product AS p 
        WHERE p.IsEnabled=1 AND
          p.BaseSku = 'KPK-3020QWC-C' 
      UNION
      SELECT       p.*
      FROM        Product AS p 
        WHERE p.IsEnabled=1 AND
          CONTAINS(p.FreeTextStrings, '"KPK-3020QWC*"')
      )
    ) SELECT * FROM AllProducts        
      WHERE RowNumber BETWEEN 1 AND 20;
    
        2
  •  1
  •   Muxa    15 年前

    这似乎很管用:

    WITH AllProducts AS (
      SELECT       p.*, Row_Number() OVER (ORDER BY ProductId) AS RowNumber
      FROM        Product AS p 
        WHERE p.IsEnabled=1 AND
        (
          CONTAINS(p.BaseSku, 'KPK-3020QWC-C') /* instead of p.BaseSku = 'KPK-3020QWC-C' */
          OR
          CONTAINS(p.FreeTextStrings, '"KPK-3020QWC*"')
        )
    ) SELECT * FROM AllProducts        
      WHERE RowNumber BETWEEN 1 AND 20;
    

    (我已经为basesku fts编制了索引)

        3
  •  0
  •   goku_da_master    12 年前

    Make sure all necessary indexes are in place. 我也有同样的问题 or 在我的一个查询中使用子句并创建包含列的非聚集索引可以修复性能。

    经过进一步的测试,这是 包含列 真正解决性能问题的索引的一部分 .以下是我为确定问题以及如何解决问题所做的:

    使用执行计划帮助您创建缺少的索引:

    如果没有索引,查询需要2分钟以上的时间,而这个时间应该在几毫秒内运行。因此,我比较了查询的执行计划与 SSMS中的子句,我需要做什么并不明显(主要是因为我不了解执行计划)。

    但是,如果您以绿色文本查看执行计划,SSMS可能会告诉您创建一个非聚集索引。隐马尔可夫模型。。。值得一试。所以我创建了索引,问题解决了!您可以右键单击“创建索引”查询并选择“缺少索引详细信息…”。这将打开一个带有完整查询的新选项卡,供您运行。给它起个名字。