第一条:去除在谓词列上编写的任何标量函数
--->在select 显示列上使用标量函数是可以的。但在where语句后的过滤条件部分对列使用函数,需要考虑。因为执行sql的引擎会因为标量函数,放弃使用该列的索引。造成扫描全表,性能下降。
--->DB V9可以使用表达式索引,但建议不要写这样的sql,索引维护代价大
--->例子
select count(id) from TBL_NMC_PAYMENTPROCESS p where year(p.REQUESTDATE)=2015
改写为:
select count(id) from TBL_NMC_PAYMENTPROCESS p where p.REQUESTDATE between '2015-01-01 00:00:00' and '2015-12-31 23:59:59'
第二条:去除在谓词列上编写的任何数学运算
--->在select 显示列上使用数学运算是可以的。但在where语句后的谓词列上使用数学运算,会将该谓词列变成不可索引列。
--->DB V9可以在列上创建索引可以使用数学运算。但不建议
--->例子:
select p.CONFIRMAMOUNT from TBL_NMC_PAYMENTPROCESS p where p.CONFIRMAMOUNT*100>1000
改写为:
select p.CONFIRMAMOUNT from TBL_NMC_PAYMENTPROCESS p where p.CONFIRMAMOUNT>1000/100
第三条:select 语句的显示列,只写必要的列,多余无用的列不需要,则不需要写。
--->降低IO的开销,排序的成本
第四条:尽可能不用DISTINCT去掉重复
--->DISTINCT很可能会使查询结果集完成一次排序,造成成本过大。其也为sql中成本最高的函数
--->使用group by去掉重复,使用in 或Exists子查询重写查询。
--->例子:
select DISTINCT p.ID,pp.ID,pp.PAYMENTID from TBL_NMC_PAYMENT p join TBL_NMC_PAYMENTPROCESS pp on p.ID=pp.PAYMENTID where p.FINISHDATE>='2014-02-18 00:00:00' and p.FINISHDATE<'2015-02-18 23:59:59'
改写为:
select p.ID,count(pp.ID) from TBL_NMC_PAYMENT p join TBL_NMC_PAYMENTPROCESS pp on p.ID=pp.PAYMENTID where p.FINISHDATE>='2014-02-18 00:00:00' and p.FINISHDATE<'2015-02-18 23:59:59' group by p.ID
改写为:
select p.ID from TBL_NMC_PAYMENT p where exists(select pp.PAYMENTID from TBL_NMC_PAYMENTPROCESS pp where p.ID=pp.PAYMENTID )
改写为:
select p.ID from TBL_NMC_PAYMENT p where p.ID in(select p.ID from TBL_NMC_PAYMENT p join TBL_NMC_PAYMENTPROCESS pp on p.ID=pp.PAYMENTID where p.FINISHDATE>='2014-02-18 00:00:00' and p.FINISHDATE<'2015-02-18 23:59:59' )