Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL多连接查询优化_Sql_Oracle_Performance_Query Optimization_Sql Tuning - Fatal编程技术网

SQL多连接查询优化

SQL多连接查询优化,sql,oracle,performance,query-optimization,sql-tuning,Sql,Oracle,Performance,Query Optimization,Sql Tuning,请告诉我如何调整此查询以获得更好的性能/执行时间 PS它是由另一个人开发并交给我的 该查询已附加(我知道这是一个巨大的问题!)-- 任何关于如何使用聚合处理联接和子查询的想法都将非常有用 SELECT /*+MONITOR*/ gcibjdnf.danfe, gcibjdnf.bjd_situacao, gcibjdnf.obs_rejeicao,

请告诉我如何调整此查询以获得更好的性能/执行时间

PS它是由另一个人开发并交给我的

该查询已附加(我知道这是一个巨大的问题!)--

任何关于如何使用聚合处理联接和子查询的想法都将非常有用

SELECT /*+MONITOR*/ gcibjdnf.danfe,
                         gcibjdnf.bjd_situacao,
                         gcibjdnf.obs_rejeicao,
                         gcibjdnf.bjd_tipo_cobranca,
                         gcibjdnf.bjd_data_vencto_cbs,
  (SELECT SUM(gcinfitens.item_valor_contratar)
                            FROM gcinfitens
                           WHERE gcinfitens.danfe = gcibjdnf.danfe) AS nf_vl_contratar,

                         (SELECT Max(id_contgrupo) FROM gcrcontitens  WHERE gcrcontitens.danfe = gcibjdnf.danfe) AS id_contgrupo,

                         (SELECT MIN(nu_interv)
                            FROM gcrcondper
                           WHERE gcrcondper.id_cond = gcccond.id_cond
                         ) AS nu_min_prz,

                         (SELECT MAX(nu_interv)
                            FROM gcrcondper
                           WHERE gcrcondper.id_cond = gcccond.id_cond
                         ) AS nu_max_prz,

                         priper.vl_taxa AS nu_taxa,
                         priper.cd_tp_taxa,
                         priper.cd_indicador,
                         gcccond.nm_cond,
                         gcccond.cd_tp_ctr,
                         priper.sg_mod AS sg_mod_cond,
                         gcccond.dt_validade,
                         gcccond.cd_sit AS cd_sit_cond,
                         gcccond.nu_car_prz,
                         gcccond.cd_base_carencia,
                         gcccond.nu_car_desc,
                         apcconc.cd_loja,
                         apcconc.cd_concess,
                         apcconc.cd_conc_mat,
                         apcconc.nm_conc,
                         apcconc.nm_apelido,
                         apcconc.cd_tp_mercado,
                         dnccontrfundo.dt_emis_ctr
                    FROM gcibjdnf
               LEFT JOIN apcconc           ON TO_CHAR(apcconc.cd_sap_dealer) = gcibjdnf.dealer_sap
               LEFT JOIN gcccond           ON gcccond.id_cond                = gcibjdnf.id_cond
               LEFT JOIN dnccontrfundo     ON dnccontrfundo.danfe            = gcibjdnf.danfe
                                          AND dnccontrfundo.cd_sit      NOT IN ('CA','RE')
               LEFT JOIN gcrcondper priper ON priper.id_cond                 = gcccond.id_cond
                                          AND priper.sq_per = 1
                   WHERE ((    apcconc.cd_concess = '1586297'
                                      OR apcconc.cd_conc_mat = '1586297') AND gcibjdnf.bjd_situacao = 'I' AND bjd_sit_interna IN ('NO', 'SD'))

                ORDER BY apcconc.nm_apelido, danfe
移动此行:

LEFT JOIN gcccond ON gcccond.id_cond = gcibjdnf.id_cond
第一个连接:

FROM
  gcibjdnf
  LEFT JOIN gcccond ON gcccond.id_cond = gcibjdnf.id_cond
..................................
因为按顺序排列联接的方式,在这些行中:

.....................
  LEFT JOIN gcrcondper gmin ON gmin.id_cond = gcccond.id_cond
  LEFT JOIN gcrcondper gmax ON gmax.id_cond = gcccond.id_cond
.........................................................
您正试图使用查询中尚未定义的表的列
gcccond.id\u cond

因此,FROM子句中的
必须是:

FROM
  gcibjdnf
  LEFT JOIN gcccond ON gcccond.id_cond = gcibjdnf.id_cond
  LEFT JOIN gcinfitens ON gcinfitens.danfe = gcibjdnf.danfe
  LEFT JOIN gcrcontitens ON gcrcontitens.danfe = gcibjdnf.danfe
  LEFT JOIN gcrcondper gmin ON gmin.id_cond = gcccond.id_cond
  LEFT JOIN gcrcondper gmax ON gmax.id_cond = gcccond.id_cond
  LEFT JOIN apcconc ON TO_CHAR(apcconc.cd_sap_dealer) = gcibjdnf.dealer_sap
  LEFT JOIN dnccontrfundo ON dnccontrfundo.danfe = gcibjdnf.danfe
  AND dnccontrfundo.cd_sit NOT IN ('CA', 'RE')
  LEFT JOIN gcrcondper priper ON priper.id_cond = gcccond.id_cond
  AND priper.sq_per = 1
ORDER BY
子句中,您还有一个非限定列
danfe

您必须使用表的名称/别名来限定它,如
dnccontrfundo.danfe
gcibjdnf.danfe

我喜欢将这样的查询分解为更小的部分,修复一部分,然后添加另一部分,一点一点地修复

我将从FROM位开始:

select *
FROM gcibjdnf
LEFT JOIN apcconc
  ON TO_CHAR(apcconc.cd_sap_dealer) = gcibjdnf.dealer_sap
LEFT JOIN gcccond 
  ON gcccond.id_cond = gcibjdnf.id_cond
LEFT JOIN dnccontrfundo
  ON dnccontrfundo.danfe = gcibjdnf.danfe
  AND dnccontrfundo.cd_sit NOT IN ('CA','RE')
LEFT JOIN gcrcondper priper
  ON priper.id_cond = gcccond.id_cond
  AND priper.sq_per = 1
WHERE (
  (apcconc.cd_concess = '1586297' OR apcconc.cd_conc_mat = '1586297')
  AND gcibjdnf.bjd_situacao = 'I'
  AND gcibjdnf.bjd_sit_interna IN ('NO', 'SD') -- assume bjd_sit_interna is in gcibjdnf
)
你应该完全符合bjd_sit_interna的资格,这样每个人都知道它在哪个表格中

我创建的表只包含此处命名的列。查询的这一部分似乎“起作用”,只是逻辑不一致

  • 您对apconc执行左联接,因此即使在apconc上没有匹配项,也应该返回一行
  • 您有一个WHERE子句,它需要apccon行,因此任何与apcconc不匹配的结果都将被过滤掉。本质上,你的左连接已经变成了一个内部连接
接下来,我添加了orderby子句

ORDER BY apcconc.nm_apelido, gcibjdnf.danfe; -- danfe must be fully qualified, else ambiguous
现在在选择列表中,您没有任何直接聚合函数;它们只存在于标量子查询中。因此,在整个查询结束时,您不需要也不可以有一个GROUP BY

事实上,查询将按原样运行,ORDER BY中的不明确列除外

不过,您可能会得到奇怪的结果,因为gcrcondper上的MIN和MAX子查询可以访问不符合连接条件的行。你确定这就是你想要的吗


除了不一致的连接逻辑和这种最小/最大奇怪之外,您的查询应该可以工作。在讨论性能之前,请检查逻辑,确保查询提供了您想要的结果。

您的问题不清楚。。你有哪些错误?SQL Developer中出现错误“%s:无效标识符”???或“GCCCOND.ID_COND”,无效标识符“…第一个与不在查询中的参数相关。。第二个是列名。。。确保你有。。。无论如何,您使用的聚合函数没有组,这应该会引发另一个错误请在代码问题中给出一个--cut&paste&runnable代码;具有期望和实际输出的示例输入(包括逐字错误消息);标签和清晰的说明和解释。这包括您能给出的最少代码,即您显示为OK的代码,由您显示为not OK的代码扩展。(调试基础。)PS您有语法错误。读语法。尽可能显示组成子表达式是正确的。明确你的问题是关于那个错误的&稍后在一篇新的帖子中重新询问你的总体目标。PS显然这里有非最小代码/数据。(以下不是语法问题,而是--)了解LEFT JOIN ON返回的内容:行上的内部连接UNION所有不匹配的左表行都由NULL扩展。始终知道作为外部联接的一部分,您需要什么样的内部联接。上的WHERE或内部联接,在上的外部联接删除任何由NULL扩展的行后,要求右[sic]表列不为NULL,即在行上只保留内部联接,即“将外部联接转换为内部联接”。你有,请读。它不仅可以帮助您提出更好的问题,还可以帮助您自己调整查询。感谢您的回答:)…我尝试过,错误被删除。但是我现在收到一个新错误:“没有一个组函数”。这显示在查询的第一行,即“SELECT gcibjdnf.danfe”,这个问题是由聚合列SUM()、MIN()、MAX()引起的。我不知道您想做什么,但我认为您需要一个
group by
子句。所有未聚合的列都必须在group by子句中(因此它将是一个巨大的列)。非常巨大,但我不确定要求。该查询涉及许多表,而且它获取的列太多,我看不出聚合的意义。@SugandhaMishra请在新帖子中提出一个新问题。但是写一个,因为这将确定引入错误的代码,帮助您自己发现错误,减少提问的需要。我对aggregate函数也有同样的感觉,尽管我不确定,因为我不是SQL方面的专家。当这个问题交给我时,我会首先分析逻辑。谢谢:)