2010/07/20

TRIGGER & PROCEDURE

HELP TRIGGER MAPA_INT_ORG_HST;

Name ActionTime Decimal Order Value Creation TimeStamp Event Kind Enabled Comment
Trig_insert_int_org           A 32,767 2009-03-17 16:39:21 I R Y ?


SHOW TRIGGER Trig_insert_int_org

REPLACE TRIGGER msttst.Trig_insert_int_org
AFTER INSERT ON msttst.MAPA_INT_ORG_HST
REFERENCING NEW AS NewRow
FOR EACH ROW
(
CALL msttst.Proc_insert_dummy_int_org(NewRow.id_int_org_pty,NewRow.user_crt,NewRow.dttm_crt,NewRow.user_upd,NewRow.dttm_upd);
);


SHOW PROCEDURE Proc_insert_dummy_int_org

REPLACE PROCEDURE msttst.Proc_insert_dummy_int_org(
IN Internal_Org_Party_Id  CHAR(4),
IN CREATED_BY    VARCHAR(20),
IN CREATION_DATE   TIMESTAMP,
IN UPDATED_BY    VARCHAR(20),
IN UPDATED_DATE    TIMESTAMP
)

EXIT_PROC:

BEGIN

DECLARE var_Key1    VARCHAR(30);
DECLARE var_Key2   VARCHAR(30);

DECLARE var_DmyCdPref   VARCHAR(10);
DECLARE var_DmyCd   VARCHAR(200);

--MAIO_INT_DPT_HST
DECLARE chr_Id_Int_Org_Pty  CHAR(4);
DECLARE var_Id_Int_Dpt_Pty  VARCHAR(50);
DECLARE dat_dt_pty_strt   DATE;
DECLARE dat_dt_pty_end   DATE;
DECLARE var_Nm_Int_Dpt_Eng  VARCHAR(50);
DECLARE var_Nm_Int_Dpt_Int  VARCHAR(50);
DECLARE var_Nm_Int_Dpt_Abr  VARCHAR(50);
DECLARE var_Dsc_Int_Dpt   VARCHAR(50);
DECLARE chr_Cd_Int_Dpt_Tp  CHAR(2);
DECLARE var_Id_Par_Int_Dpt_Pty  VARCHAR(50);
DECLARE var_Flg_Dmy   VARCHAR(1);
DECLARE var_User_Crt   VARCHAR(10);

DECLARE var_Dttm_Crt   TIMESTAMP;

DECLARE var_User_Upd   VARCHAR(10);

DECLARE var_Dttm_Upd   TIMESTAMP;

DECLARE num_rec    INTEGER;

SELECT COUNT(*) INTO num_rec
 FROM msttst.MAPA_INT_ORG_HST
 WHERE id_int_org_pty = Internal_Org_Party_Id;

IF num_rec > 1 THEN
 LEAVE EXIT_PROC;
END IF;

SET var_Key1 = 'ADMIN';
SET var_Key2 = 'MST_DUMMY';

--Get DUMMY CODE
SET var_DmyCdPref = NULL;
SELECT txt1 INTO var_DmyCdPref
 FROM msttst.MACM_GNL_MST
 WHERE key1 = var_Key1 AND
  key2 = var_Key2 AND
  flg_del = '0';

IF var_DmyCdPref IS NULL THEN
 SET var_DmyCdPref = '#';
END IF;

--CREATE DUMMY CODE
SET var_DmyCd = var_DmyCdPref || Internal_Org_Party_Id;

SET chr_Id_Int_Org_Pty  = Internal_Org_Party_Id;
SET var_Id_Int_Dpt_Pty  = var_DmyCd;
SET dat_dt_pty_strt  = '1900-01-01';
SET dat_dt_pty_end  = '9999-12-31';
SET var_Nm_Int_Dpt_Eng  = NULL;
SET var_Nm_Int_Dpt_Int  = NULL;
SET var_Nm_Int_Dpt_Abr  = NULL;
SET var_Dsc_Int_Dpt  = NULL;
SET chr_Cd_Int_Dpt_Tp  = NULL;
SET var_Id_Par_Int_Dpt_Pty = NULL;
SET var_Flg_Dmy   = '1';
SET var_User_Crt  = CREATED_BY;
SET var_Dttm_Crt  = CREATION_DATE;
SET var_User_Upd  = UPDATED_BY;
SET var_Dttm_Upd  = UPDATED_DATE;

INSERT INTO msttst.MAIO_INT_DPT_HST
VALUES(chr_Id_Int_Org_Pty,var_Id_Int_Dpt_Pty,
         dat_dt_pty_strt,dat_dt_pty_end,
                var_Nm_Int_Dpt_Eng,var_Nm_Int_Dpt_Int,
                       var_Nm_Int_Dpt_Abr,var_Dsc_Int_Dpt,
  chr_Cd_Int_Dpt_Tp,var_Id_Par_Int_Dpt_Pty,var_Flg_Dmy,
  var_User_Crt,var_Dttm_Crt,var_User_Upd,var_Dttm_Upd);
END;


2010/07/04

RoundHalfwayMagUP

sel  cast(0.000005 as dec(7,5))
      ,cast(0.000015 as dec(7,5))
      ,cast(0.000025 as dec(7,5))
      ,cast(0.000035 as dec(7,5))
      ,cast(0.000045 as dec(7,5))
      ,cast(0.000055 as dec(7,5))
      ,cast(0.000065 as dec(7,5))
      ,cast(0.000075 as dec(7,5))
      ,cast(0.000085 as dec(7,5))
      ,cast(0.000095 as dec(7,5))

FALSE
0.00000 0.00002 0.00002 0.00004 0.00004 0.00006 0.00006 0.00008 0.00008 0.00010

TRUE
0.00001 0.00002 0.00003 0.00004 0.00005 0.00006 0.00007 0.00008 0.00009 0.00010

2010/06/15

Built-in Functions in Teradata

http://readvitamin.com/2007/08/09/how-to-use-built-in-functions-in-teradata/


Written by admin in Thursday, August 9th 2007 under IT  

First of all what are Built-in functions? These are functions which do not need any sort of arguments but still returns information about the system; user, date, time, session etc. Built-in functions are sometimes referred to as special registers. Mostly used with the SELECT statement. Usage;

SELECT

• ACCOUNT: - If you are wondering about your Teradata Account information just use this function to see your current account string.

• CURRENT_DATE:- Returns the current system date and it is same as the function DATE.

• CURRENT_TIME:- This function returns the current system time and current session ‘Time Zone’ displacement. This function is similar to the TIME function but with extra feature of Time Zone displacement.

• CURRENT_TIMESTAMP:- Returns the current system timestamp (including year, month and day) and current session Time Zone displacement.

• DATABASE: - If you are wondering how to find your current database name, use this function which returns the name of the default database for the current user.

• DATE: - As mentioned earlier, it does return the current date.

• SESSION: - Returns a number for the session the current user is in. Two sessions does not have the same number. If you want to identify your session, this is the function to use.

 • TIME: - As mentioned, this function provides the current time based on a 24-hour day; mean to say for 4:00 pm, you would see 16:00:00.

 • USER: - If you have forgotten your username after you have logged in, this command would come to your rescue. This one gives the user name of the current user.

Import/Export Data by SQL Assistant

Export
SQL Assistant -> Exprort Data ->输出至文件
Import
SQL Assistant -> Import Data
insert into dwhtst.TMSL_CUST_MAJ  values (?,?,?,'Y',NULL,NULL,NULL)
执行并选择输入源文件

不过好慢

2010/06/14

SSRS动态设置URL有无

原来URL的有无也是可以设定的


=IIF(Fields!qty_act.Value Is Nothing or Fields!customer.Value = "-" or Fields!customer.Value = "" or UCASE(Fields!customer.Value) = "OTHERS",
Nothing,
"MBI_TVSIRPTRS017")

2010/06/12

TD性能调优和物理实现培训总结 2

原帖地址
http://blog.chinaunix.net/u3/103331/showart_2050758.html

总结 2
1、Parcel
   Client to Server(Request Parcel(1)、Data Parcel(0 or N)、Response Parcel)
   Parcel步骤:REQUEST PARCEL -> SYNTAXER -> RESOLVER -> SECURITY -> OPTIMIZER -> GENERATOR -> GNCApply -> AMP STEPS
   
   使用Data Parcel的好处,是可以让PE缓存执行计划,重复执行,提高效率。
   使用意见:对于那种重复执行的动作,比如重复插入一堆的数据的时候,最好将数据弄成文件的形式,采用Using 的方式在BTEQ中提交,能提高很多效率。
   如何查看执行的sql是否被cache呢?
   Answer:通过DBQLogTbl表,里面的字段CacheFlag可以查看该语句在执行的时候是否有被cache(PE的解析Cache是采用LRU算法,4个小时最长生命周期,既4个小时候会把该sql语句给unmarked)
   Parcel的RESOLVER过程,会使用系统字典表来检查sql语句是否正确,那么是否会锁系统表呢?
   Answer:Parcel的RESOLVER也是使用缓存来存系统字典表信息,不会锁系统表。Data Dictionary Cache
2、Join Strategies
   Teradata的设计思想是:Share Nothing,也就是说各个AMP之间是独立,每个AMP都不知道其他AMP到底存储有什么样的数据,所以对于Join、比较等,都需要在本AMP进行了,也就有了所有的Redistribution和Duplicate to all amp。
   Product Join:Duplicate smaller table to all amp,(not sort)
   Merge Join:Duplicate smaller table or redistribute table which don't join with pi. Sort on join column row hash.
   merge join 由于Sort column row hash,所以可以减少比较的次数(不用像Product Join那样每个都需要比较)。
   
   Join如果非正常的慢可能有以下几个情况:
   which is redistributed by hash code to all AMPs : Skew表被Redistribute了
   which is duplicated on all AMPs : 大表被Duplicate了。  
   这就涉及到一个统计信息的问题。如果收集的统计信息没有及时的更新,比如说建完一个表,收集了统计信息,然后统计信息里面这个表是小表(因为是空表)。而当这个表数据量变大时,没有更新统计信息,则优化器还是认为他是小表,可能就会duplicate这张表,那就是个大工作量了。
   
   Where条件中,关于OR操作的优化,可以采用UNION的方式,放到2个SQL语句中执行,而不做product join。
    
SELECT  Department_Name, Last_Name, First_Name 
FROM     Employee INNER JOIN Department 
ON           Employee.Department_Number = Department.Department_Number 
OR           Employee.Employee_Number = Department.Manager_Employee_Number; 
变为
SELECT  Department_Name, Last_Name, First_Name
FROM     Employee INNER JOIN Department
ON          Employee.Department_Number = Department.Department_Number
UNION UNION
SELECT  Department_Name, Last_Name, First_Name
FROM     Employee INNER JOIN Department
ON          Employee.Employee_Number = Department.Manager_Employee_Number;

   Nested Join(最简单的join):join的一个表而且有确定的where条件(UPI或者USI) ,只能选择出一条记录
3、PPI
  PPI的好处:特殊查询能力的增强,比如说按日期查询(设置按日期的PPI),避免全表扫描
  PPI可能出现的问题:多了2个字节的空间浪费(partition号),对PI的查询可能会比没有定义PPI的慢(先确定了partition在访问里面的row hash)。
  如果partition 不是PI的一部分的话,PI不能定义为UPI,而为了保证唯一性,可以定义USI在字段上。
  思考?为什么partition不是PI的一部分的话,PI不能定义为UPI
  Answer:UPI能确保唯一性,而如果partition不是PI的一部分的话,如果使用PI来Access的话,会扫描每个partition在定位,已经失去了作为UPI的意义了。
  
  DBC.IndexConstraints中ConstraintsType标志位Q的表示PPI。
  PPI的适用情形:
  1、大表
  2、partition字段经常被Access
  3、partition的数量是有限制的(65535)
4、Aggregation
  ARSA算法:
  Aggregate - Local on the AMPs
  Redistribute - The Local Aggregations
  Sort - The Redistribution Aggregations
  Aggregate - Globally for the final aggregation
  Group by VS Distinct
  1、适用情况:
     Group by 先在本AMP上分组,然后在在Globally上分组
     Distinct 是先把数据分布到All AMP上在去重。
     所以,在重复值比较多的情况下,Group by 能提高点性能,其他情况下,Distinct比较快点。(不是绝对的)
  2、关于Eliminate
     group by 没有进行eliminate操作,distinct有进行这样的操作。
     (in、not in、unique、distinct操作会去重)
5、Date
  TD中,日期以数字来存储。如2009-09-09在数据库中被转换为20090909,在数据库中存储过数字10090909(20090909-19000000)
  如果时间小于19000000则在数据库中存储为负值。
  
        SELECT EXTRACT(YEAR FROM DATE '2004-03-31') ||
        EXTRACT(MONTH FROM DATE '2004-03-31')
        result:       2004          3
        整数转换为11位字符在||
 

TD性能调优和物理实现培训总结 1

原帖地址
1、几种索引的判定:
Join Index 预先进行关联的表,类似于“物化视图”,需要占用表空间,Join Index可以自动更新。
Global Index 在选择出来的字段中有rowid
Sparse Index 在Index中使用了Where条件
Aggregate Join Index 预先在index中进行Aggregate操作(同summary table的区别:summary table需要手动更新,Aggregate Join index可以自动更新)
2、Store Procedure和Macro的区别:
   Macro和Stored Produre同样能使用变量,调用sql语句。其中Macro一般比Stored Procedure 简单,同时Stored Procedure支持SPL操作,既IF..ELSE...THEN等。
3、TDWM:Teradata Dynamic Workload Manager,混合负载管理,动态的管理资源分布和优先级。(目前正在做试验)
4、关于视图
  加视图的好处:
  1、SQL语句---保存复杂的SQL语句来直接运行
  2、保密---可以在sql语句中使用一定的方式来加密字段
  3、权限和索机制---最主要的,通过视图来限制对基表的访问,同时对基本的访问时候可以加Access锁
  基于视图的视图访问是极其没有效率的:
  可以试下语句create table tmp as (select * from t03_agreement),可以发现tmp的主键已经不是t03_agreement的主键了,嵌套视图同样的,当访问嵌套视图时候,第二个视图的索引已经没用了,会造成很大的SKEW,影响数据的选取。(根据这段时间的工作,发现在生产上还是有一些使用到了嵌套视图的。)

5、事务和锁
   事务处理系统的典型特点是具备ACID特征。ACID指的是Atomic(原子的)、Consistent(一致的)、Isolated(隔离的)以及Durable(持续的),它们代表着事务处理应该具备的四个特征。
   TD的锁这种级别:Access、Read、Write、Exclude锁。其中,DDL语句一般是Exclude锁,Insert、update一般是Write锁,Select一般是read锁。同级的锁可以互相叠加,Exclude锁除外。Access锁可以获得除Exclude锁以外的全部锁,但是可能会造成脏读的现象,视图就是以这种方式为考虑的。(问题分析,DW允许脏读的产生,因为DW多以大数据量的查询为主,比较少进行update的操作,除非是在数据批处理的时候,不像OLTP系统,需要对数据的一致性有很高的要求。)
   TD基于MPP的架构,每个AMP之间是独立的,所以对于同样的一个请求,可能会有不同的执行顺序,没有一个同步的策略,这个时候TD采用的是一个Pesudo表,这个表是每个AMP都公用的,以此来保证同步,每次需要加锁某个对象的时候,就先加Pessudo表,而不是对每个AMP进行加锁。(可以通过Explain来查看得到)
   BT ET跟Muti-statement加锁的不一样:
   1、BT ET是一个语句一个语句加锁,锁进行累积,直到遇到ET的时候才释放锁
   2、muti-statement 是一次性全部加锁
TD对于死锁机制的处理:
   在TD数据库中,每4分钟会检查一次死锁,如果出现死锁的话,就roll back 最后的那个Session
   
Presudo的思考---是不是每次访问都需要使用到Presudo表呢?
   answer:
      2个语句explain select * from table where pi字段 = ? 和explain select * from table where notpi字段= ?
      你会发现,使用pi字段的时候就不会所presudo表,这是因为TD的Presudo表是针对MPP架构设计的,如果是单个AMP操作的时候,其实就没有所谓的同步的现象,所以就不用使用Presodu。
      如上,也就是说单AMP操作不需要presodu表。
对于提交Multi-Statement Requests,将“;”号放在sql语句的前面,多个sql语句同时提交,如下
                  Update Dept 
                        set Salary_Change_Date = Date 
                 ; Update Manager 
                        set Salary_Amt = Salary_Amt *1.08 
                 ; Update Employee 
                        set Salary_Amt = Salary_Amt * 1.04;
    上述语句被放到同一个Session中提交,但是在数据库处理的时候并不是按照顺序一个个下来的,而是随机执行的,同时优化器可能根据判断,来并行的执行语句,所以不能妄图使用Multi-Statement来达到顺序执行的目的。
6、关于DBQLogtbl表
   DBQLogTbl表,是DBC的系统表,FallBack的,双倍存储空间。一般来说如果在数据库中开启了日志记录的话,这个表的空间会增长很快。
   DBQLogTbl里面有很多非常有用的信息。
   比如字段CacheFlag可以得出本sql是否使用了cache,比如说里面有CPU时间,语句执行时间等,可以由此来判断多长时间是等待,多长时间是真正执行,同时也可以日志下对于数据库的sql语句,可以由此来进行调优。
   DBQLogTbl表可以使用的策略如下:
     1、开启数据库的日志记录
     2、每天清理DBQLogTbl表,把数据库传输到一个没有fallback的表中(可以适当的删除些不需要的字段)
     3、分析导出的数据

Hash Collision 和 Skew

1.计算每个hash值的记录个数
SELECT                 HASHROW (CHARACTER_COLUMN) 
                        AS "Hash Value"
                        ,COUNT(*)
FROM                DB.TABLE
GROUP BY        1
ORDER BY        2 DESC;

2.计算每个AMP上的记录个数
SELECT                 HASHAMP (HASHBUCKET
                        (HASHROW (CHARACTER_COLUMN))) 
                        AS "AMP #"
                        ,COUNT(*)
FROM                DB.TABLE
GROUP BY        1
ORDER BY        2 DESC; 
3.查找出skew偏移严重的表

SELECT 
 DATABASE,TABLENAME,SUM(CURRENTPERM) AS TableSize,
 MAX(CURRENTPERM) * NUM_OF_AMP  AS VirtualSize,
 100 - AVG(CURRENTPERM)/MAX(CURRENTPERM) * 100 AS TableSkew,
 MAX(CURRENTPERM) * NUM_OF_AMP - SUM(CURRENTPERM) AS SkewSavings
 FROM DBC.TABLESIZE
 WHERE CURRENTPERM > 0
 GROUP BY 1,2,3
 HAVING(SkewSavings > 1000000000 and TableSkew > 10)
 OR TableSkew > 50;

2010/06/11

TUNING TIPS

BETWEEN比IN有效
IN比EXIST有效
LIKE条件的开头如果不是通配符则优化器使用索引的可能。否则进行全表扫描
DISTINCT很耗费资源(但是和GROUP BY相比如何呢?)
如果可以的话使用UNION ALL而不是UNION
使用多个SQL语句计算不同范围的合计值会导致同一个表的多次扫描,如果将
这些SQL合并,并用CASE区分范围,可以减少扫描次数。这会极大的提高性能
DISTINCT会创建临时表,可以更改SQL的结构避免DISTINCT的使用。
使用派生表而非临时表。减少磁盘IO
避免使用混合类型的表达式。例如字符串和数值比较,TERADATA会将字符串
转换成数值。这会使索引失效并导致全表扫描。结论:混合类型比较时做显示转换
SI
JI
GLOBAL JI
PPI

TBL01.A LIKE TBL02.B

SELECT DISTINCT
id_int_org_pty,
nm_ext_org_grp_pty
FROM
VMSL_CUST_MAJ
) TBL01
ON
TBL02.id_int_org_pty = TBL01.id_int_org_pty
WHERE
INDEX(TBL02.nm_ext_org_eng,TBL01.nm_ext_org_grp_pty) > 0

或者


SELECT
AB.A
FROM
AB
LEFT OUTER JOIN
BB
ON
AB.A LIKE '%' || B||'%'

EXTRACT

EXTRACT
(
YEAR
MONTH
DAY
HOUR
MINUTE
SECOND
TIMEZONE_HOUR
TIMEZONE_MINUTE
FROM value)

ANSI SQL-2003

SSRS一处BUG

设置单元格背景颜色,颜色由行中某单元格内容决定。在本地执行报表,反应正常。部署到服务器上不正常工作。

http://www.sqldev.org/sql-server-reporting-services/background-color-differences-between-visual-studio-amp-reporting-services-39081.shtml


SSRS条件语句

switch

=Switch(Fields!Orders.Value < 100,"Red", Fields!Orders.Value > 100, "Green")

iif
=IIF(Fields!LineTotal.Value > 100, True, False)

Expression Examples (Reporting Services)
http://msdn.microsoft.com/en-us/library/ms157328.aspx

2010/06/09

JOIN INDEX

A JOIN B
A,B表PI不同的情况下,需要重新分布A或者B。可以考虑在A上建立于B同PI的SINGLE TABLE JOIN INDEX,避免重新分布大量数据。
或者使用于B同PI的中间表,或者VOLATILE表。
总之尽量避免重新分布数据就好