【问题标题】:How to make TD to avoid using single amp retrieve?如何让TD避免使用单耳放检索?
【发布时间】:2017-07-27 20:35:46
【问题描述】:

我有这样的疑问:

select * from view -- not very simple logic
where report_date between date'2016-01-01' and date'2016-12-31';

那我就用大时间间隔:

TD 选择这样的计划:

3) We do an all-AMPs RETRIEVE step from Spool 25 (Last Use) by way of
     an all-rows scan with a condition of ("(REPORT_DT >= DATE
     '2016-01-01') AND (REPORT_DT <= DATE '2016-12-31')") into Spool 36
     (all_amps) (compressed columns allowed) fanned out into 3 hash

但如果我采取的间隔不是那么大,它决定对每个数据进行简单的 amp 检索:

   select * from view -- not very simple logic
    where report_date between date'2016-06-01' and date'2016-12-31';

239) We do a single-AMP RETRIEVE step from
     tableName1 by way of the unique
     primary index "tableName1.gregor_dt =
     DATE '2016-08-08'" extracting row ids only with no residual
     conditions locking row for access into Spool 43 (group_amps),
     which is built locally on that AMP.  The size of Spool 43 is
     estimated with low confidence to be 221 rows.  The estimated time
     for this step is 0.00 seconds.

1) 由于假脱机问题,第二次查询失败。如何强制 teradata 使用第一个计划?

更新1

  • 没有双重转换,只是从一种日期格式转换为 另一个。
  • 两个计划都使用重新分配,除了指出的地方,我没有区别。
  • TD 高估了行数,最多 2-3 次(我在评论中给出了错误的信息)
  • 我们在 DEV 中拥有几乎相同数量的信息和统计数据。然而,DEV 服务器的 AMPS 和节点数量减少了 2 倍,此外每个 amp 的功能明显降低。然而,开发中的 TD 开始决定在较短的时间间隔内使用第一个“好”计划。我们如何才能在这一点上“愚弄”PROD 服务器?)

【问题讨论】:

  • 很可能是因为您的标准prd3_1_db_dmmonmis.t_greg_work_calendar.gregor_dt = DATE '2016-08-08 将您限制为单个放大器上的数据。你展示的这两个解释步骤彼此完全没有关系。
  • @Andrew:这是 TD15.10 中的新功能,BETWEEN 可能会在优化之前解析为唯一值列表。
  • 奇怪,第二个查询遇到了假脱机问题,可能为以后的步骤解释更改。您可能会尝试通过添加一些不必要的 CAST(如 Cast(Cast(report_date AS TIMESTAMP) AS DATE))来混淆优化器,但如果完全错误,请检查估计的行数。
  • @dnoeth:所以上面的查询可能会为between 中的每个不同日期获取一堆单个放大器检索?我们已经 14 岁了,所以我不能尝试。
  • @Andrew:是的,正确的。

标签: sql performance query-optimization teradata spool


【解决方案1】:

我做到了!要让它发挥作用,只需要欺骗 TD 两次)

查询的思想是取表,然后产品加入到Sys_Calendar,然后应用row_number和一些逻辑。删除统计数据可能有效,但 TD 可能会使用抽样和兑现,这最终会影响您的工作。这就是我在视图中应用expand + 子查询的原因:

...
FROM   (    SEL cdate as cdate FROM (SELECT   DISTINCT      BEGIN      (tp) (NAMED cdate) 
    FROM           Sys_Calendar.CALDATES
    EXPAND       ON PERIOD (date '2014-01-01', current_date + 1) AS tp
    BY INTERVAL '1' DAY FOR PERIOD (date '2014-01-01',  current_date  + 1)
    ) A)  cldr
...

之后,我可以使用where 子句申请我想要的期限。

新计划的速度甚至比“好”计划快 15 倍!

【讨论】:

  • 您真的需要在应用 DISTINCT 之前先创建 73414*1165(日历中的#days * 2014-01-01 和今天之间的#days)行吗?如果你把它简化为... FROM (SELECT Begin (tp) (Named cdate) FROM Sys_Calendar.CALENDAR WHERE calendar_date = DATE '2014-01-01' EXPAND ON PERIOD (calendar_date, Current_Date + 1) AS tp ) cldr ...
  • @dnoeth 似乎是这样。对于我的解决方案 - TD 认为这将是 55k 行,你的 - 只是 1。
猜你喜欢
  • 2019-09-11
  • 1970-01-01
  • 2020-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
相关资源
最近更新 更多