【发布时间】:2017-01-17 22:11:12
【问题描述】:
我正在尝试修改一个包含 1 亿行的表,以便可以有效地维护和查询它。我们每个月都会为该表获得大约一百万行新行。 我以为我已经正确设置了它,主索引平均分配行和范围分区,其中一个是按日期,但是当我尝试将表更改为当前日期以添加新分区时,花费了太长时间。
现在我不确定我还应该改变什么。我的理解是参与 PI 和分区的每个字段都应该被索引并为解析引擎收集统计信息,即使维护这些索引和统计信息需要时间和空间。
我曾考虑将日期范围延长几年以避免更改分区,但我也了解到 Teradata 不推荐这种做法。
那么我还应该尝试什么?这是我的创建声明:
CREATE SET TABLE STAGE.PartD
DATABLOCKSIZE = 1048064 BYTES
(
Efctv_uniq_id CHAR(13) NOT NULL,
Cntrct_num CHAR(5) NOT NULL COMPRESS ('H2407','H2416','H2417','H2419','H2422','H2425','H2450','H2456','H2457','H2458','H2459','H2462','H5703','S0522','S4802','S5597','S5601','S5617','S5644','S5660','S5743','S5768','S5803','S5810','S5820','S5884','S5921','S5932','S5960','S5967','S7694'),
Pbp_id SMALLINT NOT NULL COMPRESS (1 ,2 ,24 ,25 ,42 ,50 ,59 ,83 ,94 ,370 ,122 ,123 ,145 ,162 ,247 ),
Hicn VARCHAR(20) NOT NULL,
Cardhldr_id VARCHAR(20) COMPRESS '',
Ptnt_date_of_birth DATE FORMAT 'YY/MM/DD' COMPRESS ,
Ptnt_gender_cd CHAR(1) NOT NULL COMPRESS ('0','1','2'),
Date_of_srvc DATE FORMAT 'YY/MM/DD' NOT NULL,
Paid_dt DATE FORMAT 'YY/MM/DD' COMPRESS ,
Product_srvc_id VARCHAR(19) NOT NULL COMPRESS ('~','62175011843','00088222033'),
Srvc_prvdr_id_qlfyr CHAR(2) NOT NULL COMPRESS ('01','07','99'),
Srvc_prvdr_id VARCHAR(15) NOT NULL,
Fill_num BYTEINT NOT NULL COMPRESS (0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ),
Dspnsng_stus CHAR(1) NOT NULL COMPRESS ' ',
Cmpnd_cd CHAR(1) COMPRESS '1',
Daw_prod_slctn_cd CHAR(1) COMPRESS '0',
Qty_dspnsd CHAR(10) NOT NULL COMPRESS ('0000004000','0000010000','0000014000','0000015000','0000020000','0000028000','0000030000','0000031000','0000045000','0000056000','0000060000','0000090000','0000100000','0000120000','0000180000'),
Days_suply SMALLINT COMPRESS (0 ,3 ,5 ,7 ,10 ,14 ,15 ,20 ,25 ,28 ,30 ,31 ,34 ,90 ),
Prscrb_id_qlfyr CHAR(2) COMPRESS (' ','01','12'),
Prscrb_id VARCHAR(15) NOT NULL COMPRESS '',
Drug_cvrg_stus_cd CHAR(1) COMPRESS (' ','C','E','O'),
Adjsmt_del_cd CHAR(1) COMPRESS (' ','A','D'),
Non_stand_frmt_cd CHAR(1) COMPRESS (' ','B','C','X'),
Prcng_excptn_cd CHAR(1) COMPRESS (' ','M','O'),
Uniq_id CHAR(13) NOT NULL,
FinalVersionInd CHAR(1),
LoadID SMALLINT NOT NULL)
PRIMARY INDEX pi ( Efctv_uniq_id ,LoadID )
PARTITION BY ( RANGE_N(LoadID BETWEEN 1 AND 10000 EACH 1 ),
RANGE_N(Date_of_srvc BETWEEN DATE '2007-01-01' AND ADD_MONTHS((DATE ),(-1 )) EACH INTERVAL '1' MONTH ) )
UNIQUE INDEX ui ( Efctv_uniq_id ,LoadID )
INDEX Efctv_uniq_id ( Efctv_uniq_id )
INDEX Date_of_srvc ( Date_of_srvc )
INDEX LoadID ( LoadID );
我需要暂存环境中的 UI,因此它不允许多次加载相同的数据。我已将该索引从 prod 环境中的表中删除。
avgCurrentPerm 为 722027691,maxPeakPerm 为 730772992,skewFactor 为 0.094412。
感谢您的帮助。
改为:
PRIMARY INDEX pi ( Efctv_uniq_id ,LoadID )
PARTITION BY (
RANGE_N(LoadID BETWEEN 644 AND 10000 EACH 1 ),
RANGE_N(Date_of_srvc BETWEEN DATE '2007-01-01' AND DATE '2030-01-01'
EACH INTERVAL '1' MONTH ) );
看到: avgCurrentPerm 377035904 maxPeakPerm 377372160 skewFactor 0.089105
并收集这些统计数据:
COLLECT STATS
COLUMN (PARTITION),
COLUMN (loadid),
COLUMN (Efctv_uniq_id),
COLUMN (Date_of_srvc)
ON STAGE.PartD;
我的印象是使用当前日期创建唯一索引和分区范围是个坏主意?
【问题讨论】:
-
不确定是否投反对票,如果需要其他信息,我可以提供。我正在寻找超出我已经找到的用于优化 Teradata 中的大型表的一般建议。
标签: teradata