日期:2014-05-16  浏览次数:20795 次

如何优化该SQL语句
各表主键:
表M_PSNMONTHACCOUNTRECORD的主键;表M_SJ_M_PERSON主键STATMONTH, PSNSN;表M_SJ_M_CORPORATION主键STATMONTH, CORPSN。  
SQL语句:
SELECT *
  FROM (SELECT 16 AS AGE,
  A.FEEMONTH,
  B.FEEAREA,
  C.CORPTYPE,
  COUNT(B.PSNSN),
  SUM(A.FEEBASE)
  FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
  M_SJ_M_PERSON B,
  M_SJ_M_CORPORATION C
  WHERE A.PSNSN = B.PSNSN
  AND B.STATMONTH = C.STATMONTH
  AND B.CORPSN = C.CORPSN
  AND B.AGE <= 16
  AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
  GROUP BY A.FEEMONTH, B.FEEAREA, C.CORPTYPE
  UNION
  SELECT B.AGE,
  A.FEEMONTH,
  B.FEEAREA,
  C.CORPTYPE,
  COUNT(B.PSNSN),
  SUM(A.FEEBASE)
  FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
  M_SJ_M_PERSON B,
  M_SJ_M_CORPORATION C
  WHERE A.PSNSN = B.PSNSN
  AND B.STATMONTH = C.STATMONTH
  AND B.CORPSN = C.CORPSN
  AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
  GROUP BY B.AGE, A.FEEMONTH, B.FEEAREA, C.CORPTYPE
  HAVING B.AGE BETWEEN 17 AND 64
  UNION
  SELECT 65 AS AGE,
  A.FEEMONTH,
  B.FEEAREA,
  C.CORPTYPE,
  COUNT(B.PSNSN),
  SUM(A.FEEBASE)
  FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
  M_SJ_M_PERSON B,
  M_SJ_M_CORPORATION C
  WHERE A.PSNSN = B.PSNSN
  AND B.STATMONTH = C.STATMONTH
  AND B.CORPSN = C.CORPSN
  AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
  AND B.AGE >= 65
  GROUP BY B.FEEAREA, A.FEEMONTH, B.FEEAREA, C.CORPTYPE)

------解决方案--------------------
1、把UNION 想办法去掉
2、GROUP尽量少用
------解决方案--------------------
优化如下:
SELECT case when A.AGE <= 16 then 16 
when A.AGE >= 65 then 65
else A.AGE end age,
A.FEEMONTH,
B.FEEAREA,
C.CORPTYPE,
COUNT(B.PSNSN),
SUM(A.FEEBASE)
FROM BJMEDICARE_SJ.M_PSNMONTHACCOUNTRECORD A,
M_SJ_M_PERSON B,
M_SJ_M_CORPORATION C
WHERE A.PSNSN = B.PSNSN
AND B.STATMONTH = C.STATMONTH
AND B.CORPSN = C.CORPSN
AND A.FEEPSNTYPE NOT IN (12, 13, 14, 17)
GROUP BY case when A.AGE <= 16 then 16 
when A.AGE >= 65 then 65,
else A.AGE end,A.FEEMONTH, B.FEEAREA, C.CORPTYPE

------解决方案--------------------
这三个表的数据量如何呢?
------解决方案--------------------
1,Oracle从右到左处理From子句中的表名,所以在From子句中包含多个表的情况下,将记录最少的表放在最后
2, not in 不走索引,可以试着改用 not exists