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秒,哪个大侠有好的解决办法没有啊,多谢啦
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秒,哪个大侠有好的解决办法没有啊,多谢啦
关于多表操作 用连接已经是效率高的 了 所以此处的left join没问题 也估计没法优化了。。
,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'
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'
才能使用到索引?
-----在不修改主键的情况下是的。