【问题标题】:TSQL - extract data to table/view to speed up queryTSQL - 将数据提取到表/视图以加快查询速度
【发布时间】:2015-05-14 17:58:11
【问题描述】:

我用这个语句为excel创建一个列表

SELECT DISTINCT Year, Version 
    FROM myView 
    WHERE id <> 'old' 
    ORDER BY Year DESC, Version DESC

问题是执行时间超过 30 秒,因为将近 200 万行。

结果只有大约 1000 行。

为了加快执行时间,我有哪些选项可以仅提取这两列?我还需要确保识别到基础表的插入。

我需要一个新表来复制视图中的值吗?以及管理更新的触发器?

谢谢

【问题讨论】:

  • 你能发布你的表定义吗?包括索引?
  • 这三列YearVersionid是否都来自同一张表?
  • 既然这是我要问的一个观点,那这个观点是否引用了另一个观点?最可能的问题是 where 子句中的 nonSARGable 谓词 。无论您做什么,都会导致表/索引扫描。
  • 您可以为此查询创建一个特定的索引...“Year DESC,Version DESC”上的过滤索引,其中过滤器是 id 'old' ...然后此查询将使用它索引,它会非常快。但是,该索引不会被任何其他查询使用,任何更新、插入和删除都必须更新该索引。
  • - 没有为该表定义索引(并且它不适用于该表) - 所有列都来自同一个表 - 这就是为什么我认为创建一个额外的表可能会更好对于这两列

标签: sql-server tsql select triggers sql-server-2012


【解决方案1】:

因此,您的视图中可能有一张带有 Year 和 id 的表格。鉴于这个(微不足道的)示例:

CREATE TABLE myTable ([id] varchar(10), [Year] int, [Version] int);

只需在该表上创建一个与您查询数据的方式相匹配的索引。鉴于您的查询:

SELECT DISTINCT Year, Version 
  FROM myView 
 WHERE id <> 'old' 
 ORDER BY Year DESC, Version DESC

此查询与 WHERE 和 ORDER BY 子句匹配,应该为您提供所需的所有性能:

IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[myTable]') AND name = N'IX_YearVersion_Filtered')
    DROP INDEX [IX_YearVersion_Filtered] ON [dbo].[myTable] WITH ( ONLINE = OFF )
GO
CREATE NONCLUSTERED INDEX [IX_YearVersion_Filtered] ON [dbo].[myTable] 
(
    [Year] DESC,
    [Version] DESC
)
WHERE ([id]<>'old')
GO

【讨论】:

    【解决方案2】:
    with cte_x
    as
    (SELECT Year, Version 
        FROM myView 
        WHERE id not in ('old')
        group by Year, Version)
    SELECT DISTINCT Year, Version 
        FROM cte_x
            ORDER BY Year DESC, Version DESC
    

    【讨论】:

    • 感谢您的示例 - 但是查询速度只快了几秒钟
    猜你喜欢
    • 1970-01-01
    • 2016-12-12
    • 2012-11-06
    • 2021-06-05
    • 2012-12-28
    • 2021-11-30
    • 1970-01-01
    • 2015-06-01
    • 2014-10-04
    相关资源
    最近更新 更多