数据库查询优化的一些总结
查询优化经验总结
对于大表,数据先过滤 再关联 性能最好
尽量避免全表扫描
如果根据大表的某个计算结果比较频繁,应该将其作为临时表,缓存结果,比如投资者持仓数据
索引
索引的基础概念
在关系数据库中,索引是一种与表有关的数据库结构,它可以使对应于表的SQL语句执行得更快。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。
当表中有大量记录时,若要对表进行查询:
第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;
第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录。
索引的优点
1.大大加快数据的检索速度;
3.加速表和表之间的连接;
4.在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
索引的缺点
1.索引需要占物理空间。
2.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。
Teradata中PI使用的一个例子
PI索引不仅对查询有影响,对数据迁移也会造成很大的影响
一个千万级数据量的表,本想通过如下语句将数据汇总并导入一个新表中:
CREATE SET TABLE DSS_TTemp.STKT_AL_SELL_DAILY_AGG_MONTH
AS
(
SELECT cast((cast(Day_Id as format 'YYYYMM')) as char(6)) as Day_Id,
cast((cast(Tkg_Dt as format 'YYYYMM')) as char(6) ) as Tkg_Dt,
Agc_IATA_Cd,Agc_Cty_Cd,Carr_Cd,Arrv_Airpt_Cd,Arrv_Cty_Cd,
Arrv_Cntry_Cd,Dpt_Airpt_Cd,Dpt_Cty_Cd,Dpt_Cntry_Cd,Cls_Cd,
Tkt_Typ_Ind,Tkt_Fmt_Typ,Tkt_Txn_Typ,Eqt_Crncy_Cd,Grp_Ind,Tour_Cd,
sum(D_Seg_Qty) as D_Seg_Qty,sum(I_Seg_Qty) as I_Seg_Qty,
sum(Tax_Amt) as Tax_Amt,sum(Commsn_Amt) as Commsn_Amt,
sum(Net_Amt) as Net_Amt,sum(Tkt_Amt) as Tkt_Amt ,
sum(Tkt_Qty) as Tkt_Qty,sum(Pax_Qty) as Pax_Qty
FROM DSS_TTemp.STKT_AL_SELL_DAILY_AGG
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
)
WITH DATA;
结果在第一次执行时,跑了15个多小时还没完。通过查看Explain Plan,发现该sql一直卡在merge过程中。百思不得其解,请教老员工才知道,原来是PRIMARY INDEX的问题:Teradata默认将新表的第一个字段day_id作为了主索引,由于日期取值范围比较小,导致Teradata算出的ROW HASH值重复比较多,使得数据在磁盘中的分配极不平均,主要集中在某几个AMP中,所以插入时会相当的慢。
Teradata数据库主索引
- 主索引的概念
- 哈希值的存储方法
- PI对数据库查询性能的影响
在进行Teradata数据库的逻辑设计时,对于每一个表,都要指定一个“主索引”(Primary Index,简称PI),Teradata数据库引擎会根据这个主索引的实际值,同时根据系统的配置情况(主要是AMP的个数),通过一种哈希算法,为每个表的每一条数据都生成一个“行哈希值”(Row Hash Value),Teradata会根据这个行哈希值把数据分布到某一个确定的AMP上。
数据分布的过程中,在值20和30所在列上定义了Primary Index,系统的哈希算法根据20和30这两个值,生成了两个不同的行哈希值,之后系统根据这两个行哈希值的内容,把20和30各自所对应的行分别分布到了不同的AMP上进行存储了。
在获取数据的时候(SELECT、UPDATE、DELETE都是获取数据的SQL操作),系统会使用与进行数据分布时相同的哈希算法对20和30进行哈希运算,这会得到相同的行哈希值,系统就根据这个行哈希值直接定位到20或者30各自所在的AMP,并由各自对应的AMP返回要获取的行。
根据哈希算法,对于不同的Primary Index值,可能会计算出相同的行哈希值,这些具有相同的行哈希值的数据行就会被分布在同一个AMP上。这样,如果哈希算法选择得当,则可以基本保证,同一个表中的数据在整个Teradata并行系统的多个AMP上的分布是趋于均匀的。
对于一个Teradata系统,其哈希算法是确定的,而且是运行时不可变的,在系统的硬件不变的前提下(AMP数不变),这就保证了对于同一个Primary Index值,所生成的行哈希值也是相同的。因此,对于不同的表,尤其是有主-外键关联关系的表,通过慎重地定义Primary Index,可以做到那些经常要进行关联(往往是主-外键关联)的行会被分布到同一个AMP上,这大大缩短了数据库进行数据关联的时间,提高了Teradata系统的性能。