在开发中,有这么一个需求:
   在原有的列表页面再添加几列,那么久需要在查询的SQL语句再添加几个字段的查询,这几个字段我暂时取名叫做aNumber,bNumber,cNumber,dNumber,它们的作用是统计A表中与主表关联的记录条数,B表中与主表关联的记录条数,C表中与主表关联的记录条数,D表中与主表关联的记录条数,这里只需要统计出统计条数即可。A,B,C,D表和主表Main的关系是Main表的主键分别是这4张表的外键,例如我写入的SQL语句如下:select 
  t.*--主表字段,原来页面需要的字段
  (select count(0) from A a where  a.tid=t.tid) aNumber,--A表的外键tid等于t表的主键tid,查出A表与主表关联的记录数
  (select count(0) from B b where  b.tid=t.tid) bNumber,--B表的外键tid等于t表的主键tid,查出B表与主表关联的记录数
  (select count(0) from C c where  c.tid=t.tid) cNumber,--C表的外键tid等于t表的主键tid,查出C表与主表关联的记录数
  (select count(0) from D d where d.tid=t.tid) dNumber,--D表的外键tid等于t表的主键tid,查出D表与主表关联的记录数
from main t where 条件语句前提条件:主表Main分别与A,B,C,D表都是一对多的关系,不能left join查询的时候,让记录数莫名其妙的多出来,上诉的SQL查询到的数据应该没什么问题的,最主要的问题就是太慢,查询速度慢到领导以为页面出现了,数据一致出不来

解决方案 »

  1.   

    不加这一堆主表,是否很快能出结果? 如果也很慢,应该先优化主表这个查询。如果主查询很快,加了子查询才慢,可以如下操作方法试试:
    1、在各个子表的tid列上,加索引。 这个比较常见的方法。
    2、把语句拆成多个子步骤
    创建多个临时表,并增加相关索引
    create temporary table ta(tid int primary key, cnt int)
    insert into ta select tid, count(*) from A group by tidselect t.*, ta.cnt from main t left join ta on t.tid = ta.tid
      

  2.   

    1. 先看一下查询计划:explain plan for select ...;
    select * from table(dbms_xplan.display);很多开发工具直接能查看,比如 SQL Developer。2. 大概率是 A,B,C,D 表上的 tid 字段没有索引,那就加上,快到飞起。
      

  3.   

    首先,你给的语句逗号位置有问题,会报错。
    其次,在abcd这4个表上,tid字段加索引,并把语句改成这个样子,可能会有提升。如果每个表的tid差异性不大,建议试一下位图索引。
    如果abcd表数据变化不大,可以把SELECT TID,COUNT(TID) C FROM A的结果初始化到某个表里,用这个新建的表来实现这个功能,肯定比这么查快的多。
    select 
     t.*,--主表字段,原来页面需要的字段
     (select count(a.tid) from A a where a.tid=t.tid) aNumber,--A表的外键tid等于t表的主键tid,查出A表与主表关联的记录数
     (select count(b.tid) from B b where b.tid=t.tid) bNumber,--B表的外键tid等于t表的主键tid,查出B表与主表关联的记录数
     (select count(c.tid) from C c where c.tid=t.tid) cNumber,--C表的外键tid等于t表的主键tid,查出C表与主表关联的记录数
     (select count(d.tid) from D d where d.tid=t.tid) dNumber--D表的外键tid等于t表的主键tid,查出D表与主表关联的记录数
    from main t where 条件语句 ;
      

  4.   

    看一下主查询和A B C D的行源信息,我就知道优化方法了
      

  5.   


    要精准优化,得有SQL语句的执行计划和数据环境,不然,就是大概的猜测,靠猜测,简单的SQL可以猜到,复杂点的不行。