Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用CTE优化时态表

用CTE优化时态表
EN

Stack Overflow用户
提问于 2019-03-04 10:49:24
回答 9查看 825关注 0票数 7

我创建时态表是为了设置级别:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE [#DesignLvl]
(
    [DesignKey] INT,
    [DesignLevel] INT
);

WITH RCTE AS 
(
    SELECT
        *,
        1 AS [Lvl]
    FROM 
        [Design]
    WHERE 
        [ParentDesignKey] IS NULL

    UNION ALL

    SELECT
        [D].*,
        [Lvl] + 1 AS [Lvl]
    FROM 
        [dbo].[Design] AS [D]
    INNER JOIN 
        [RCTE] AS [rc] ON [rc].[DesignKey] = [D].[ParentDesignKey]
)
INSERT INTO [#DesignLvl]
    SELECT
        [DesignKey], [Lvl]
    FROM 
        [RCTE]

创建之后,我在真正的大查询中使用了左联接,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT... 
FROM.. 
LEFT JOIN [#DesignLvl] AS [dl] ON d.DesignKey = dl.DesignKey
WHERE ...

查询工作正常,但性能下降,查询速度太慢。有办法优化这张桌子吗?

CTE的执行计划

我尝试将聚集索引添加为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE [#DesignLvl]
(
    [DesignKey] INT,
    [DesignLevel] INT
);

CREATE CLUSTERED INDEX ix_DesignLvl 
    ON [#DesignLvl] ([DesignKey], [DesignLevel]);

还试着:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    CREATE TABLE [#DesignLvl] 
( [DesignKey] INT INDEX IX1 CLUSTERED ,
 [DesignLevel] INT INDEX IX2 NONCLUSTERED );

但我得到了同样的结果,需要很长时间才能执行

EN

回答 9

Stack Overflow用户

发布于 2019-03-06 16:03:05

性能可能更慢,因为在嵌套循环中访问dbo.Design表上的聚集索引。根据成本估算,数据库花费了66%的时间扫描该索引。翻个圈只会让事情变得更糟。

请参阅相关问题

考虑将dbo.Design上的索引更改为非聚集索引,或尝试使用非聚集索引创建另一个临时表,并将其用于递归查询:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE [#DesignTemp]
(
    ParentDesignKey INT,
    DesignKey INT
);

-- Insert the data, then create the index.
INSERT INTO [#DesignTemp]
SELECT
ParentDesignKey,
DesignKey
FROM [dbo].[Design];

COMMIT;

-- Try this index, or create indexes for individual columns if the plan works better at high volumes.
CREATE NONCLUSTERED INDEX ix_DesignTemp1 ON [#DesignTemp] (ParentDesignKey, DesignKey);

CREATE TABLE [#DesignLvl]
(
    [DesignKey] INT,
    [DesignLevel] INT
);

WITH RCTE AS 
(
    SELECT
        *,
        1 AS [Lvl]
    FROM 
        [DesignTemp]
    WHERE 
        [ParentDesignKey] IS NULL

    UNION ALL

    SELECT
        [D].*,
        [Lvl] + 1 AS [Lvl]
    FROM 
        [DesignTemp] AS [D]
    INNER JOIN 
        [RCTE] AS [rc] ON [rc].[DesignKey] = [D].[ParentDesignKey]
)
INSERT INTO [#DesignLvl]
    SELECT
        [DesignKey], [Lvl]
    FROM 
        [RCTE];
票数 4
EN

Stack Overflow用户

发布于 2019-03-06 22:49:40

您的问题是不完整的,“查询很慢”,但是查询的哪一部分比较慢?

CTEQueryLEFT JOIN in really big query

我认为需要大查询的脚本,以及详细信息,比如哪个表包含多少行、它们的数据类型等等。

抛出更多有关大查询的详细信息。

还请让我们知道是否有任何UDF涉及到连接条件。

你为什么要left join临时表?为什么不INNER JOIN

分别测试性能或CTE和Big。

一旦在递归部分中使用了[D].[ParentDesignKey] is not null

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT
        [D].*,
        [Lvl] + 1 AS [Lvl]
    FROM 
        [dbo].[Design] AS [D]
    INNER JOIN 
        [RCTE] AS [rc] ON [rc].[DesignKey] = [D].[ParentDesignKey]
and [D].[ParentDesignKey] is not null

注意: CTE中的只使用那些需要的列。

如果可以的话,Pre- Calculate [Lvl],因为Recursive CTE的性能特别差,涉及到很多记录。

平均每个CTE查询将处理多少行?

如果临时表的容纳量超过100 rows,则可以在其上创建聚集索引,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  CREATE CLUSTERED INDEX ix_DesignLvl 
        ON [#DesignLvl] ([DesignKey], [DesignLevel]);

如果在联接条件下不使用[DesignLevel],则从索引中删除。

同时,还揭示了表[dbo].[Design]的索引以及DesignKey和ParentDesignKey的少量数据。

获得Index Scan有几个原因,其中之一就是Selectivity of Key

因此,一个DesignKey可以有多少行,一个ParentDesignKey可以有多少行?

因此,根据上面的答案,Create Composite Clustered Index在表[dbo].[Design]的两个键上

因此,考虑到我的回答是不完整的,我会相应地更新它。

票数 3
EN

Stack Overflow用户

发布于 2019-03-04 11:52:20

根据我在这篇文章上发布的测试,基于集合的循环可以比递归的CTE提高性能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DECLARE @DesignLevel int = 0;

INSERT INTO [#DesignLvl]
SELECT [DesignKey], 1
FROM [RCTE];

WHILE @@ROWCOUNT > 0
BEGIN
    SET @DesignLevel += 1;

    INSERT INTO [#DesignLvl]
    SELECT [D].[DesignKey], dl.DesignLevel
    FROM [dbo].[Design] AS [D]
    JOIN [#DesignLvl] AS [dl] ON [dl].[DesignKey] = [D].[ParentDesignKey]
    WHERE dl.DesignLevel = @DesignLevel;
END;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54989684

复制
相关文章
[PostgreSQL] - CTE
1、PostgreSQL CTE语句与materialized 2、7.8. WITH查询(公共表表达式)
夹胡碰
2022/09/19
7130
[PostgreSQL] - CTE
Flink1.12新特性之Flink SQL时态表小总结
Flink 1.12正式发布后,带来了很多新的特性,本文重点学习和总结一下Flink 1.11和 Flink1.12中时态表的使用和自己的一个小总结,文章如有问题,请大家留言交流讨论,我会及时改正。
大数据真好玩
2021/09/18
1.1K0
SQL优化(五) PostgreSQL (递归)CTE 通用表表达式
原创文章,转载请务必将下面这段话置于文章开头处(保留超链接)。 本文转发自技术世界,原文链接 http://www.jasongj.com/sql/cte/ CTE or WITH WITH语句通常被称为通用表表达式(Common Table Expressions)或者CTEs。 WITH语句作为一个辅助语句依附于主语句,WITH语句和主语句都可以是SELECT,INSERT,UPDATE,DELETE中的任何一种语句。 例讲CTE WITH语句最基本的功能是把复杂查询语句拆分成多个简单的部分,如下
Jason Guo
2018/06/11
2.7K0
SQL优化技巧--远程连接对象引起的CTE性能问题
背景    最近SSIS的开发过程中遇到几个问题。其中使用CTE时,遇到一个远程连接对象,结果导致严重的性能问题,为了应急我就修改了代码。   之前我写了一篇介绍CTE的随笔包含了CTE的用法等:
用户1217611
2018/01/30
1.5K0
SQL优化技巧--远程连接对象引起的CTE性能问题
SQLServer CTE 递归查询
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,递归查询主要用于层次结构的查询,从叶级(Leaf Level)向顶层(Root Level)查询,或从顶层向叶级查询,或递归的路径(Path)。
挽风
2021/04/13
1.7K0
SQLServer CTE 递归查询
SQL递归查询(with cte as)
  递归CTE最少包含两个查询(也被称为成员)。第一个查询为定点成员,定点成员只是一个返回有效表的查询,用于递归的基础或定位点。第二个查询被称为递归成员,使该查询称为递归成员的是对CTE名称的递归引用是触发。在逻辑上可以将CTE名称的内部应用理解为前一个查询的结果集。
跟着阿笨一起玩NET
2018/09/18
1.3K0
「嘤嘤嘤glish」时态总结
请注意,本文编写于 1063 天前,最后修改于 1063 天前,其中某些信息可能已经过时。
曼亚灿
2023/05/17
2500
InnoDB表优化
OPTIMIZE TABLE 语句通过拷贝表数据并重建表索引,使得索引数据更加紧凑,减少空间碎片。语句的执行效果会因表的不同而不同。过大的表或者过大的索引及初次添加大量数据的情况下都会使得这一操作变慢。
WindWant
2020/09/11
1.1K0
优化表(一)
要确保InterSystems IRIS®Data Platform上的InterSystems SQL表的最高性能,可以执行多种操作。优化可以对针对该表运行的任何查询产生重大影响。本章讨论以下性能优化注意事项:
用户7741497
2022/06/08
1K0
优化表(二)
从管理门户运行Tune Table工具时,ExtentSize是表中当前行的实际计数。默认情况下,GatherTableStats()方法还将实际行数用作ExtentSize。当表包含大量行时,最好对较少的行执行分析。可以使用SQL tune table命令并指定%SAMPLE_PERCENT来仅对总行的一定百分比执行分析。在针对包含大量行的表运行时,可以使用此选项来提高性能。此%SAMPLE_PERCENT值应该足够大,以便对代表性数据进行采样。如果ExtentSize<1000,则无论%SAMPLE_PERCENT值如何,TUNE TABLE都会分析所有行。
用户7741497
2022/06/08
1.8K0
Mysql优化-表分区
已经基于行级锁的话,就没有办法从软件层面提升并发度了,否则会事务冲突。所以思路:行级锁、物理层面提升。
码客说
2019/10/21
4.3K0
枚举+优化(3)——哈希表优化实例
例1. //两重循环枚举,时间复杂度O(N^2) #include <bits/stdc++.h> using namespace std; int n,k,a[100000]; set<pair<i
mathor
2018/06/07
4570
Oracle优化之单表分页优化
SQL> create table t_test as select * from dba_objects;
星哥玩云
2022/08/17
9260
评论模块优化 - 数据表优化、添加缓存及用 Feign 与用户服务通信
前段时间设计了系统的评论模块,并写了篇文章 评论模块 - 后端数据库设计及功能实现 讲解。
solocoder
2022/04/06
6550
评论模块优化 - 数据表优化、添加缓存及用 Feign 与用户服务通信
大数据表查询优化 - 表分区
快两年没写过业务代码了…… 今天帮一个研发团队优化了一下数据库表的查询性能。使用的是表分区。 简单记录了一下步骤,方便直接用:
用户1172223
2020/10/09
1K0
PostgreSQL - SQL调优方案
有个更好的办法,是安装扩展pg_stat_statements,此处需要PostgreSql支持,部分版本需要编译安装:
雨临Lewis
2022/03/08
2.1K0
枚举+优化(4)——哈希表优化实例2
例3.四平方和 思路1:枚举abcd,判断a^2^+b^2^+c^2^+d^2^是否等于N  分析规模  a:0 ~ sqrt(500000 / 4)  b:0 ~ sqrt(500000 /
mathor
2018/06/08
6960
Flink SQL 优化实战 - 维表 JOIN 优化
作者:龙逸尘,腾讯 CSIG 高级工程师 背景介绍 维表(Dimension Table)是来自数仓建模的概念。在数仓模型中,事实表(Fact Table)是指存储有事实记录的表,如系统日志、销售记录等,而维表是与事实表相对应的一种表,它保存了事实表中指定属性的相关详细信息,可以跟事实表做关联;相当于将事实表上经常重复出现的属性抽取、规范出来用一张表进行管理。 在实际生产中,我们经常会有这样的需求,以原始数据流作为基础,关联大量的外部表来补充一些属性。例如,在订单数据中希望能获取订单收货人所在市区的名称。一
腾讯云大数据
2022/05/30
3.9K0
Flink SQL 优化实战 - 维表 JOIN 优化
Mysql大表优化方案
除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量:
若与
2018/04/25
2.8K0
Mysql大表优化方案
MySQL大表优化方案
1、尽量不要在一开始就考虑表拆分,会带来逻辑、部署、运维的各种复杂度; 2、一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下问题不大; 注意: 1、Covering index:索引覆盖:即当索引本身包含查询所需全部数据时,不再访问数据文件本身,也就是不再需要回表操作; 2、复合索引顺序:理论上索引对顺序是敏感的,但是由于MySQL的查询优化器会自动调整where子句的条件顺序以使用适合的索引 优化 1、字段 尽量使用TINYINT、SMALLINT、MEDIUMINT作为整数
用户8639654
2021/08/23
1.1K0

相似问题

CTE表优化

11

优化CTE查询

12

用CTE语句创建表

11

优化CTE查询

120

如何优化时态SQL Server表的性能

18
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文