导出 SQL 查询疑难解答

Posted

技术标签:

【中文标题】导出 SQL 查询疑难解答【英文标题】:Exporting SQL query trouble shooting 【发布时间】:2019-12-22 15:22:25 【问题描述】:

我已经编写了一个查询,并且能够成功运行它。当我尝试导出它时,它的导出速度非常慢,即每 10-15 分钟 50 行,我设法在 10 小时内导出了大约 50K 数据。如果此查询有任何问题,请帮助我。我正在使用 sql 开发人员

谢谢

我想要的结果是按列显示的:

|GLUSR_USR_CUSTTYPE_NAME|GLUSR_USR_ID|S_COUNT|MAX_DATE as Last Meeting|Min_DATE as first Meeting|Total Meeting in Last 90 Days|Total Meeting in last 180 days| active in last 30 Days| active in last 60 Days| active in last 90 Days|

sql:

Select GLUSR_USR_ID,
    GLUSR_USR_CUSTTYPE_NAME,
    ( select  Count(1)                   from STS_DSR_SALES@mainr,STS_Company@mainr where STS_DSR_SALES.FK_STS_COMPANY_ID=CompanyID and GLUSR_USR_ID=STS_FK_GLUSR_ID)S_COUNT,
    (Select MAX(STS_DSR_SALES_DATE)      from STS_DSR_SALES@mainr,STS_Company@mainr where STS_DSR_SALES.FK_STS_COMPANY_ID=COMPANYID)MAX_DATE,
    (Select min(STS_DSR_SALES_DATE)      from STS_DSR_SALES@mainr,STS_Company@mainr where STS_DSR_SALES.FK_STS_COMPANY_ID=COMPANYID)Min_DATE,
    (Select count (1) STS_DSR_SALES_DATE from STS_DSR_SALES@mainr,STS_COMPANY@mainr where STS_DSR_SALES.FK_STS_COMPANY_ID= COMPANYID and GLUSR_USR_ID=STS_FK_GLUSR_ID and trunc(STS_DSR_SALES_DATE)>SYSDATE-90)last_90,
    (Select count (1) STS_DSR_SALES_DATE from STS_DSR_SALES@mainr,STS_COMPANY@mainr where STS_DSR_SALES.FK_STS_COMPANY_ID= COMPANYID and GLUSR_USR_ID=STS_FK_GLUSR_ID and trunc(STS_DSR_SALES_DATE)>SYSDATE-180)last_180,
    (Select Count (1) STS_DSR_SALES_DATE from STS_DSR_SALES@mainr,GLUSR_CLCKSTRM_4HOTLEAD_ARCH@mainr where GLUSR_USR_ID=FK_GLUSR_USR_ID and STS_DSR_SALES_DATE=Report_DATE and TRUNC(REPORT_DATE)>SYSDATE-30)ACTIVE_30,
    (Select Count (1) STS_DSR_SALES_DATE from STS_DSR_SALES@mainr,GLUSR_CLCKSTRM_4HOTLEAD_ARCH@mainr where GLUSR_USR_ID=FK_GLUSR_USR_ID and STS_DSR_SALES_DATE=Report_DATE and TRUNC(REPORT_DATE)>SYSDATE-60)ACTIVE_60,
    (Select Count (1) STS_DSR_SALES_DATE from STS_DSR_SALES@mainr,GLUSR_CLCKSTRM_4HOTLEAD_ARCH@mainr where GLUSR_USR_ID=FK_GLUSR_USR_ID and STS_DSR_SALES_DATE=Report_DATE and TRUNC(REPORT_DATE)>SYSDATE-90)ACTIVE_90
 From
    (
        select GLUSR_USR_ID, fk_sts_company_id,GLUSR_USR_CUSTTYPE_NAME 
        from STS_DSR_SALES@mainr,GLUSR_USR@mainr,STS_COMPANY@MAINR         
        where STS_FK_GLUSR_ID=GLUSR_USR_ID
        and fk_sts_company_id=CompanyID
        and    trunc(sts_dsr_sales_date) between '01-oCT-19' and '31-oCT-19'
    )  

【问题讨论】:

那些预期结果是不可读的,并且您标记了 2 个完全不同的 RDBMS。仅标记您实际使用的内容。 Bad habits to kick : using old-style JOINs 不幸的是,这里几乎没有任何特定信息可供任何人提供任何信息,除了猜测。数据库调优只关注细节。请阅读this answer on asking questions about Oracle query optimization,然后编辑您的问题以提供更多信息。 您使用的是古老的连接语法(旧的逗号分隔连接而不是显式内部连接)。而且,我们不知道哪些列属于哪些表。请用表格限定每一列。 (例如是sts_dsr_sales.companyid 还是glusr_usr.companyid 还是sts_company.companyid?)然后,请解释你的表。它们包含什么,它们的键是什么? 【参考方案1】:

为了获得答案/结果,您访问表格的次数过多。 尝试使用 WITH() 子句构建内联查询,并一次一个地逐步构建数据管道。

With Q1 as ( 
inline_query on 2 tables STS_DSR_SALES and STS_Company which defines the overall scope of your query/ask 
),
Q2 as (
select ... <All/90/180 day aggregates defined via sum(case statements)>
from Q1 inner join <other_table T3 GLUSR_USR>
where ... (keys)
),
Q3 as (
select ... <All/30/60/90 day aggregates defined via sum(case statements)>
from Q1 inner join <other_table T4 GLUSR_CLCKSTRM_4HOTLEAD_ARCH>
where ... (keys)
)
--final result
select * from (
select * from Q2 inner join Q3 on ...
)
pivot ( 
-- convert rows to cols ... get your KPIs to line up as columns 
);

【讨论】:

【参考方案2】:

很难了解全貌,因为您指的是没有表名/别名的列,并且依赖于这些确切的名称仅出现在其中一个表中,而且您正在从 select 子句中进行选择。

您的查询似乎有很多具有最小/最大或不同日期范围的重复部分。我很确定这些可以使用case 语句组合成较少数量的查询,比如

sum(case when TRUNC(REPORT_DATE)>SYSDATE-30 then 1 end),
sum(case when TRUNC(REPORT_DATE)>SYSDATE-60 then 1 end),
sum(case when TRUNC(REPORT_DATE)>SYSDATE-90 then 1 end),

所以你会摆脱一些查询。

不再记得这是否是一件坏事(或仅在 SQL Server 中),而且自从我上次使用 Oracle 以来已经有十多年了,所以事情可能也发生了变化 :)

但您可能想测试替换它:

trunc(sts_dsr_sales_date) between '01-oCT-19' and '31-oCT-19'

用这样的东西,你就可以摆脱这个功能:

sts_dsr_sales_date >= '01-OCT-19' and sts_dsr_sales_date < '1-NOV-19' 

【讨论】:

永远不要依赖隐式数据类型转换。以及为什么在千年虫 20 年后,我们仍然使用 2 位数的年份。应该是 'sts_dsr_sales_date >= to_date('01-OCT-2019','dd-MON-yyyy') 和 sts_dsr_sales_date 我同意 EdStevens,但无论如何你都应该使用日期文字:sts_dsr_sales_date &gt;= date '2019-10-01' and sts_dsr_sales_date &lt; date '2019-11-01' 确切地说,Oracle SQL 中日期文字的语法是(例如)date '2019-11-01',因为 the documentation 已经明确多年(链接到 10g 文档以表明它不是新的 - 这实际上是在 9i 中添加)。即使是经验丰富的开发人员也经常出错,这总是让我感到惊讶。

以上是关于导出 SQL 查询疑难解答的主要内容,如果未能解决你的问题,请参考以下文章

SQL oracle的一些问题求解答

sql语句,怎么将一段日期分割成每日?请高人解答。

疑难杂症 - SQL语句整理

SQL 经典题型解答

关于SQL语句的执行先后顺序,希望高手解答并写出原因。谢谢,

数据库sql题目解答