【问题标题】:SQL Query performance (break-up one query into smaller ones or not)SQL 查询性能(是否将一个查询分解为较小的查询)
【发布时间】:2018-09-20 03:59:59
【问题描述】:

我有一个 SQL 查询(在 Teradata 平台上运行),它具有 1) 内连接 2)where子句 3) 分组

运行大约需要 40 分钟,我想让它更快。 (我没有权限为此表创建索引)。代码如下。我是否应该只使用 WHERE 子句和另一个中间表来创建一个中间表 W 来过滤掉与表 X 相交的 W 的行,然后最后进行内部连接?

    create table ABC as
    (select 
        b.acct_nb,
        max(b.lst_pmt) as pmt       
     from
     Y as b inner join X as a on 
     a.acct_nb = b.acct_nb
     where b.amount > 0
     group by b.acct_nb
     );

建议代码:

    create table W as
    select acct_nb,amount
    from Y
    where amount > 0;

    create table W2 as
    select a.acct_nb,b.amount
    from X as a inner join W as b
    on a.acct_nb = b.acct_nb;


    create table ABC as
    select a.acct_nb,max(b.lst_pmt) as pmt
    from W2 as a inner join Y as b
    on a.acct_nb = b.acct_nb
    group by b.acct_nb;

退出;

【问题讨论】:

  • 您的Create Table as Select 语法无效。表和本地主键和外键的行数是多少?其中一张表中的acct_nb 是唯一的吗?你能分享解释吗?
  • 这是现有代码中交给我的语法。我不是数据科学家,但这些查询需要大约 1 小时才能运行。我没有特权在这个特定的表上运行 EXPLAIN - 我相信它是一个根本无法修改的表。我通过SAS的PROC SQL访问SQL,数据库是Teradata。
  • 关于行数:X 中大约 790 万行,Y 中未知,甚至更多,因为这是一个包含数十年信息的数据库。主键是 acct_nb。我也没有权限运行 EXPLAIN。

标签: sql performance teradata database-performance


【解决方案1】:

建议的代码可能不会提高性能。

如果没有 Explain 或 QueryLog 信息,很难给出建议,但您可以尝试在加入之前进行聚合:

select b.*
from 
 (
   select 
      acct_nb,
      max(lst_pmt) as pmt       
   from Y
   where amount > 0
   group by b.acct_nb
 ) as b 
inner join X as a 
on a.acct_nb = b.acct_nb

【讨论】:

  • 我认为这可能是答案......当我在 SAS 上运行它以访问 Teradata 时,我提出的代码给了我一个错误::空间不足“或类似的东西。所以分解成更小的查询我所做的就是要走的路。我尝试运行这个版本,我认为它运行了,但我的系统很快就崩溃了。我应该早先添加的一点信息:X 有 7.9 磨机行,但 Y 有 284 磨机行。
【解决方案2】:

这是您的查询:

create table ABC as
    select b.acct_nb, max(b.lst_pmt) as pmt       
    from Y b inner join
         X a 
         on a.acct_nb = b.acct_nb
    where b.amount > 0
    group by b.acct_nb;

您并没有真正使用X(过滤除外),所以我想知道这是否符合您的要求:

create table ABC as
    select b.acct_nb, max(b.lst_pmt) as pmt       
    from Y b 
    where b.amount > 0
    group by b.acct_nb;

如果没有,您可以改用exists

create table ABC as
    select b.acct_nb, max(b.lst_pmt) as pmt       
    from Y b 
    where b.amount > 0
          exists (select 1 from X a where a.acct_nb = b.acct_nb)
    group by b.acct_nb;

我会在使用临时表之前尝试这些方法。

【讨论】:

  • 如果我使用选项 2,我仍然需要过滤掉不在 X 中的行。这不会使其整体变慢吗?我必须在关键变量 acct_nb 上添加表 ABC 和 X 之间的内部连接?我会试试这个并在明天发布....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
相关资源
最近更新 更多