select t1.billid,t1.CompanyID,t8.unitno
from (select  c1.BillID, c1.CompanyID, c1.DebtorID,  c1.BillItemID, c1.DocumentNo, c1.DocumentDate, c1.DueDate, c1.Re, c1.ExchangeRate, c1.DocumentAmt, c1.BalanceAmt
            ,isnull(c1.UnitID,(select top 1 c2.UnitID from view_MC_getalldebtorinfo c2 where c2.debtorid=c1.debtorid)) as UnitID,c1.RefTable
,c2.AdjustAmt
      from ar_trx c1 left join
           (select sum(Convert(decimal(22,10),abs(DocumentAmt)*ExchangeRate)) as AdjustAmt,RefRecordID 
 from ar_trx 
where RecordStatus='Active' and isnull(RefTable,'')='ar_trx'
group by  RefRecordID) c2 on c1.BillID=c2.RefRecordID inner join
           ar_billitem c3 on c1.billitemid=c3.billitemid and c3.itemcode not in('RT.Deposit','RT.DestineEarnest')
       where c1.RecordStatus='Active' and isnull(RefTable,'')<>'ar_trx') t1 inner join
     ar_debtor t2 on t1.debtorid=t2.debtorid inner join
     cf_account t3 on t2.accountid=t3.accountid inner join
     MC_Property t4 on t2.RefProjectRecordID =t4.PropertyID and t2.RefProjectTable='MC_Property' inner join
     ar_billitem t5 on t1.billitemid=t5.billitemid and t5.ItemCode not in('RT.Deposit','RT.DestineEarnest') inner join
     cf_popuplstelement t6 on t5.billtypeid=t6.popuplstelementID left join
     cf_popuplstelement t7 on t5.ReportHeaderID=t7.popuplstelementID  inner join
     MC_Unit t8 on t1.UnitID=t8.UnitID 因为数据量有点大,发现速度很慢,就想对SQL优化一下,经查,问题出在最后的
inner join     MC_Unit t8 on t1.UnitID=t8.UnitID ,如果不加这个内连接,只要6秒,一加上后时间去到26秒,整整多了20秒,哪个大侠有好的解决办法没有啊,多谢啦

解决方案 »

  1.   

    可以这么说吧
    关于多表操作 用连接已经是效率高的 了 所以此处的left join没问题 也估计没法优化了。。
      

  2.   

    问题出这里,查出来的UNITID没有索引,再去关联其它表的时候速度就变慢了。是否有其它的解决方法呢?select  c1.BillID, c1.CompanyID, c1.DebtorID,  c1.BillItemID, c1.DocumentNo, c1.DocumentDate, c1.DueDate, c1.Re, c1.ExchangeRate, c1.DocumentAmt, c1.BalanceAmt 
                ,isnull(c1.UnitID,(select top 1 c2.UnitID from view_MC_getalldebtorinfo c2 where c2.debtorid=c1.debtorid)) as UnitID,c1.RefTable 
    ,c2.AdjustAmt 
          from ar_trx c1 left join 
              (select sum(Convert(decimal(22,10),abs(DocumentAmt)*ExchangeRate)) as AdjustAmt,RefRecordID 
    from ar_trx 
    where RecordStatus='Active' and isnull(RefTable,'')='ar_trx' 
    group by  RefRecordID) c2 on c1.BillID=c2.RefRecordID inner join 
              ar_billitem c3 on c1.billitemid=c3.billitemid and c3.itemcode not in('RT.Deposit','RT.DestineEarnest') 
          where c1.RecordStatus='Active' and isnull(RefTable,'') <>'ar_trx'
      

  3.   

    想优化的话 索引比较好 
    1.表的主键、外键必须有索引;2、数据量超过300的表应该有索引;3、经常与其他表进行连接的表,在连接字段上应该建立索引;4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;5、索引应该建在选择性高的字段上;6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:  A、正确选择复合索引中的主列字段,一般是选择性较好的字段;  B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;  C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;  D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;  E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;8、频繁进行数据操作的表,不要建立太多的索引;9、删除无用的索引,避免对执行计划造成负面影响; 以上是一些普遍的建立索引时的判断依据。一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。因为太多的索引与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。
    动作描述                使用聚集索引  使用非聚集索引外键列                      应            应主键列                      应            应列经常被分组排序(order by) 应            应返回某范围内的数据          应          不应小数目的不同值              应          不应大数目的不同值            不应            应频繁更新的列              不应          应频繁修改索引列            不应          应一个或极少不同值          不应          不应 select * from TB where [companyCode]='yy' and b in('XX','ZZ')
    能使用到索引吗?
    -----用到聚集主键select * from TB where [companyCode]='yy' and (b='XX'or b='ZZ')
    能使用到索引吗?如果不能使用到索引.去掉一个主键字段c,重新生成索引,是否就能使用到索引了呢?
    -----用到聚集主键如果能使用索引,跟
    select * from TB where [companyCode]='yy' and b='XX'
    union all
    select * from  TB where [companyCode]='yy' and b='ZZ'
    的效率是不是一样?
    -----这种情况是一样的最近接触到一些进销存系统
    发现[companyCode]在同一表中都为同一值'yy'.
    这样建立的意义是什么?
    -----这你要问设计者,如果这样的数据情况,可能主键就应该是b+c了如果[companyCode]为同一值,那:
    select * from TB where b='XX' 
    或者
    select * from TB where c='CC'
    也就能直接使用到索引了吗?
    -----不能,除非你把主键修改成b+c
    如果为同一值:
    存在表TB1,TB2 索引结构类似TB
    SELECT * FROM TB1 INNER JOIN TB2 on  TB1.b=TB2.b where TB1.b='XX'
    是否也能使用到该索引?
    -----不能,除非你把主键修改成b+c是否必须加上:
    SELECT * FROM TB1 INNER JOIN TB2 on  TB1.companyCode=TB2.companyCode  and TB1.b=TB2.b where TB1.b='XX' 
    或者是
    SELECT * FROM TB1 INNER JOIN TB2 on  TB1.companyCode=TB2.companyCode  and TB1.b=TB2.b where  TB1.companyCode='yy' and TB1.b='XX' 
    才能使用到索引?
    -----在不修改主键的情况下是的。
      

  4.   

    要加的索引我都加了,就是我上面说的因为该处的unitid相当于是从一个视图中来的,这个时候是不是就用不到这个索引了。