如何优化此 SQL Server 查询 - 多个子查询

     2023-04-14     176

关键词:

【中文标题】如何优化此 SQL Server 查询 - 多个子查询【英文标题】:How to optimize this SQL Server query - Multiple subqueries 【发布时间】:2020-07-24 22:41:07 【问题描述】:

我在 SQL Server 中有这个带有 4 个子查询的查询,我正在寻找优化它的方法:

 DECLARE @INICIO DATE
 DECLARE @FIN DATE
 SET @INICIO='2020-06-17'
 SET @FIN='2020-07-27'

 SELECT VALO.FECHA_VALORACION,
        VALO.CODIGO_PORTAFOLIO,
        VALO.CUSIP,
        VALO.NUMERO_INVERSION,
        VALO.SM_GRUPO 
        SM_TIPO,
        VALO.TIPO_INSTRUMENTO DESCRIPCION_INSTMT,
        VALO.CODIGO_MONEDA CODIGO_MONEDA_PAGAR, 
        VALO.CODIGO_MONEDA CODIGO_MONEDA_RECIBIR,
        VALO.ID_CONTRAPARTE,
        OP.PRECIO 
        PRECIO_FX,
        VALO.VALOR_NOMINAL,
        VALO.VALOR_DERECHO,
        VALO.VALOR_OBLIGACION,
        VALO.VALOR_UTILIDAD_PERDIDA, 
        OP.FECHA FECHA_OPERACION,
        VALO.TIPO_OPERACION,
        OP.VALOR_OPERACION  VALOR_OPERACION_COP,
        OP.FECHA_VENCIMIENTO,
        VALO.SM_GRUPO,
        VALO.VALOR_UTILIDAD_PERDIDA_DER,
        VALO.VALOR_UTILIDAD_PERDIDA_OBL,
        (SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
         FROM Spirit.TSPT_VALORACION_FUT NESTED 
         WHERE NESTED.CUSIP=VALO.CUSIP
           AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO 
           AND FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0)
           AND FECHA_VALORACION<=VALO.FECHA_VALORACION 
           AND VALOR_UTILIDAD_PERDIDA>0
         GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS UTILIDAD_MENSUAL,
        (SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
         FROM Spirit.TSPT_VALORACION_FUT NESTED 
         WHERE NESTED.CUSIP=VALO.CUSIP
           AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO 
           AND FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0)
           AND FECHA_VALORACION<=VALO.FECHA_VALORACION 
           AND VALOR_UTILIDAD_PERDIDA<0
         GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS PERDIDA_MENSUAL,
        (SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
         FROM Spirit.TSPT_VALORACION_FUT NESTED 
         WHERE NESTED.CUSIP=VALO.CUSIP
         AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO 
           AND NESTED.FECHA_VALORACION<=VALO.FECHA_VALORACION 
           AND NESTED.VALOR_UTILIDAD_PERDIDA>0
         GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS UTILIDAD_ACUMULADA,
        (SELECT SUM(NESTED.VALOR_UTILIDAD_PERDIDA)
         FROM Spirit.TSPT_VALORACION_FUT NESTED 
         WHERE NESTED.CUSIP=VALO.CUSIP
           AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO 
           AND FECHA_VALORACION<=VALO.FECHA_VALORACION
           AND VALOR_UTILIDAD_PERDIDA<0
         GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS PERDIDA_ACUMULADA
FROM Spirit.TSPT_VALORACION_FUT VALO 
     INNER JOIN Spirit.TSPT_OPERACIONES OP ON OP.NUMERO_INVERSION = VALO.NUMERO_INVERSION
            AND OP.TIPO_OPERACION = VALO.TIPO_OPERACION
            AND OP.SM_GRUPO IN ('OPTION') 
WHERE VALO.SM_GRUPO IN ('OPTION')
  AND VALO.CODIGO_PORTAFOLIO IN ('AFP-P','AFP-F')
  AND VALO.FECHA_VALORACION >= @INICIO
  AND VALO.FECHA_VALORACION <= @FIN
ORDER BY VALO.CUSIP,VALO.FECHA_VALORACION

但我不知道如何整合它并获得最佳效果。非常感谢。

这是之前优化过程的结果。

我一直在尝试这样的:

(SELECT sum (case when NESTED.VALOR_UTILIDAD_PERDIDA > 0 then NESTED.VALOR_UTILIDAD_PERDIDA else 0 end) as UTILIDAD_MENSUAL,
        sum (case when NESTED.VALOR_UTILIDAD_PERDIDA < 0 then  NESTED.VALOR_UTILIDAD_PERDIDA else 0 end) as PERDIDA_MENSUAL
    FROM Spirit.TSPT_VALORACION_FUT NESTED 
WHERE NESTED.CUSIP=VALO.CUSIP
  AND NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO 
  AND FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0) 
  AND FECHA_VALORACION<=VALO.FECHA_VALORACION 
  AND VALOR_UTILIDAD_PERDIDA>0
GROUP BY CUSIP,CODIGO_PORTAFOLIO) AS ACUMULADOS

【问题讨论】:

仅供参考,空格和换行符使 SQL 可读。 【参考方案1】:

由于您的所有子查询似乎都来自同一个表,您可以将它们合并到 FROM 子句中的单个查询中...试试这个...如果没有要引用的表架构 ...

DECLARE @INICIO DATE
DECLARE @FIN DATE

SET @INICIO='2020-06-17'
SET @FIN='2020-07-27'

SELECT
    VALO.FECHA_VALORACION,
    VALO.CODIGO_PORTAFOLIO,
    VALO.CUSIP,
    VALO.NUMERO_INVERSION,
    VALO.SM_GRUPO
    SM_TIPO,
    VALO.TIPO_INSTRUMENTO DESCRIPCION_INSTMT,
    VALO.CODIGO_MONEDA CODIGO_MONEDA_PAGAR,
    VALO.CODIGO_MONEDA CODIGO_MONEDA_RECIBIR,
    VALO.ID_CONTRAPARTE,
    OP.PRECIO
    PRECIO_FX,
    VALO.VALOR_NOMINAL,
    VALO.VALOR_DERECHO,
    VALO.VALOR_OBLIGACION,
    VALO.VALOR_UTILIDAD_PERDIDA,
    OP.FECHA FECHA_OPERACION,
    VALO.TIPO_OPERACION,
    OP.VALOR_OPERACION VALOR_OPERACION_COP,
    OP.FECHA_VENCIMIENTO,
    VALO.SM_GRUPO,
    VALO.VALOR_UTILIDAD_PERDIDA_DER,
    VALO.VALOR_UTILIDAD_PERDIDA_OBL,
    S.UTILIDAD_MENSUAL,
    S.PERDIDA_MENSUAL,
    S.UTILIDAD_ACUMULADA,
    S.PERDIDA_ACUMULADA
FROM
    Spirit.TSPT_VALORACION_FUT VALO
    INNER JOIN Spirit.TSPT_OPERACIONES OP ON
        OP.NUMERO_INVERSION = VALO.NUMERO_INVERSION
        AND OP.TIPO_OPERACION = VALO.TIPO_OPERACION
        AND OP.SM_GRUPO IN ('OPTION')
    OUTER APPLY (
        SELECT
            SUM(CASE WHEN FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0) AND VALOR_UTILIDAD_PERDIDA>0
                THEN NESTED.VALOR_UTILIDAD_PERDIDA
                ELSE 0
            END) UTILIDAD_MENSUAL,

            SUM(CASE WHEN  FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0) AND VALOR_UTILIDAD_PERDIDA<0 
                THEN NESTED.VALOR_UTILIDAD_PERDIDA
                ELSE 0
            END) PERDIDA_MENSUAL,

            SUM(CASE WHEN NESTED.VALOR_UTILIDAD_PERDIDA>0 
                THEN NESTED.VALOR_UTILIDAD_PERDIDA
                ELSE 0
            END) UTILIDAD_ACUMULADA,

            SUM(CASE WHEN VALOR_UTILIDAD_PERDIDA<0
                THEN NESTED.VALOR_UTILIDAD_PERDIDA
                ELSE 0 END
            ) PERDIDA_ACUMULADA
        FROM
            Spirit.TSPT_VALORACION_FUT NESTED
        WHERE
            FECHA_VALORACION<=VALO.FECHA_VALORACION AND 
            NESTED.CUSIP = VALO.CUSIP AND
            NESTED.CODIGO_PORTAFOLIO=VALO.CODIGO_PORTAFOLIO
        GROUP BY
            CUSIP,
            CODIGO_PORTAFOLIO
    ) S
WHERE
    VALO.SM_GRUPO IN ('OPTION')
    AND VALO.CODIGO_PORTAFOLIO IN ('AFP-P','AFP-F')
    AND VALO.FECHA_VALORACION >= @INICIO
    AND VALO.FECHA_VALORACION <= @FIN
ORDER BY
    VALO.CUSIP,
    VALO.FECHA_VALORACION

【讨论】:

它告诉我:“在包含外部引用的聚合表达式中指定了多个列。如果正在聚合的表达式包含外部引用,则该外部引用必须是表达式中引用的唯一列。 " Line " SUM(CASE WHEN FECHA_VALORACION>=dateadd(month, datediff(month, 0, @INICIO), 0) AND FECHA_VALORACION0 THEN NESTED.VALOR_UTILIDAD_PERDIDA ELSE 0 END) UTILIDAD_MENSUAL" 没问题...你能给我一个查询中的两个表的 CREATE TABLE 定义吗? 试试这个...我能够将更常见的条件从 CASE 语句中移到 WHERE CLAUSE 中。

如何在子查询 SQL Server 中选择多个项目

】如何在子查询SQLServer中选择多个项目【英文标题】:HowtoselectmultipleitemsinasubquerySQLServer【发布时间】:2015-12-0213:16:35【问题描述】:我有一个查询,它使用子查询选择多个项目:SELECTDISTINCTA2P.aid,P.pidFROMsub_aminer_author2paperA2P,sub_am... 查看详情

如何避免多个子查询作为表达式(SQL优化)

】如何避免多个子查询作为表达式(SQL优化)【英文标题】:Howtoavoidmultiplesubqueryasexpression(SQLoptimization)【发布时间】:2017-11-0309:27:30【问题描述】:我有两张桌子表Auser_idexternal_party_id16表Buser_idactivateduser_modesale_mode1false\'Customer\'... 查看详情

优化 SQL:如何重写此查询以提高性能? (使用子查询,摆脱 GROUP BY?)

】优化SQL:如何重写此查询以提高性能?(使用子查询,摆脱GROUPBY?)【英文标题】:OptimizeSQL:Howtorewritethisquerytoboostperformance?(Usesubqueries,getridofGROUPBY?)【发布时间】:2019-12-2900:51:10【问题描述】:我正在使用MySQL5.7.18-16。我使用... 查看详情

从多个表中创建 Sql Server VIEW GROUPing BY,选择子查询作为别名

...【问题描述】:基于此帖子:MSVersionofThisMySQLViewwithGROUPBY?如何添加子查询?我想要添加到该视图中的只是一 查看详情

有关优化此多层(具有多层子查询)SQL 查询的提示

...含6层子查询的查询,目前的结构是这样的。我期待建议如何:减少层数而不重复相同的语句(例如,我可以将\'casewhenE& 查看详情

如何编写此查询以在 Sql Server 中获得更好的性能?删除子字符串行

】如何编写此查询以在SqlServer中获得更好的性能?删除子字符串行【英文标题】:HowtowritethisqueryforbetterperformanceinSqlServer?RemovingSubStringrows【发布时间】:2018-07-2308:24:42【问题描述】:如何编写此查询以获得更好的性能?SELECTT1.flo... 查看详情

SQL Server 中的 SQL 查询优化

...行度,我检查了onthislink并行度数会影响查询的性能,我如何检查服务器的并行度数是多少?如何降低这个成本?我不知道如何才能降低此成 查看详情

WHERE 子句中的 SQL 查询子选择优化 (SQL Server)

】WHERE子句中的SQL查询子选择优化(SQLServer)【英文标题】:SQLQuerysubselectoptimizationinWHEREclause(SQLServer)【发布时间】:2014-02-0310:30:03【问题描述】:我编写了以下SELECT语句:SELECTDISTINCTsomeColumn1FROMsomeTableWHEREsomeColumn2=(SELECTMAX(someColumn2)... 查看详情

多个连接子查询 SQL Server 2008

】多个连接子查询SQLServer2008【英文标题】:MultiplejoinssubquerySQLServer2008【发布时间】:2012-06-1415:18:43【问题描述】:在左侧,您将看到我为一个表设计的设计,在右侧,您将看到下面SQL中子查询的结果。我正在尝试在tblClaims上的... 查看详情

优化 SQL Server 聚合查询

...布时间】:2013-09-0405:50:13【问题描述】:我正在寻找有关如何优化此查询的想法。我已经评估了执行计划,但它没有为缺少索引提供任何想法,所以只是好奇编写查询是否更好(不同的策略)会导致更快/更轻的查询。SELECT[Place],... 查看详情

如何使用过滤器和分页优化 SQL Server 查询?

】如何使用过滤器和分页优化SQLServer查询?【英文标题】:HowtooptimizeSQLServerquerywithFiltersandPagination?【发布时间】:2018-02-0813:50:33【问题描述】:我需要此查询的优化建议(无权修改索引),出于安全原因,我省略了一些变量名... 查看详情

大型sql server查询性能优化

...此写了一个查询,但查询很长,加载数据需要太多时间。如何优化此查询?SQLQueryExecutionPlan【问题讨论】:没有人将筛选那个巨大的XML执行计划并给你一个答案。您应该先做一些跑腿工作,然后向我们征求 查看详情

从 SQL Server 查询优化器生成多个脚本

】从SQLServer查询优化器生成多个脚本【英文标题】:GenerateMultipleScriptsfromSQLServerQueryOptimizer【发布时间】:2011-10-1416:28:56【问题描述】:我环顾四周,但找不到这个问题的答案,所以我想我会问。所以我正在对几个长存储过程使... 查看详情

如何在 SQL Server 中使用子查询而不是视图

】如何在SQLServer中使用子查询而不是视图【英文标题】:HowToUseaSub-QueryinsteadofaViewInSQLServer【发布时间】:2021-04-0200:16:48【问题描述】:我有一个包含许多记录和重复ID的表。我正在尝试按每个ID分组并显示最新日期的记录。只能... 查看详情

使用子查询优化 SQL 查询

】使用子查询优化SQL查询【英文标题】:OptimizingSQLQuerywithSubquery【发布时间】:2018-04-2016:30:23【问题描述】:我有一个包含地址和组织名称的表格。在某些情况下,同一地址可以与多个组织相关联,而在其他情况下,同一地址-... 查看详情

如何使用其中的一些子查询优化此查询

】如何使用其中的一些子查询优化此查询【英文标题】:Howtooptimizethisquerywithsomesubqueriesinit【发布时间】:2013-03-1810:05:46【问题描述】:我的查询是这样的:SELECTdate_format(created_at,\'%Y-%m-%d\')ASthe_date,COUNT(s.id)AStotal,(SELECTCOUNT(ks.id)FRO... 查看详情

为啥此相关子查询在 Oracle 和 SQL Server 中的工作方式不同

】为啥此相关子查询在Oracle和SQLServer中的工作方式不同【英文标题】:WhythiscorrelatedsubqueryworksdifferentlyinOracleandSQLServer为什么此相关子查询在Oracle和SQLServer中的工作方式不同【发布时间】:2019-12-0723:41:14【问题描述】:我有表EMPLO... 查看详情

如何使用 SQL Server 透视多个列

】如何使用SQLServer透视多个列【英文标题】:HowtoPIVOTmultiplecolumnsusingSQLServer【发布时间】:2021-11-1201:52:06【问题描述】:我刚刚编写了一个查询(用于SQLServer),它返回此输出:VendorIdCategoryFirstSaleDateStoreId1Car1/1/2021121Clothes1/2/2021... 查看详情