MySql批量插入优化Sql执行效率实例详解
MySql批量插入优化Sql执行效率实例详解
itemcontractprice数量1万左右,每条itemcontractprice插入5条日志。
updateInsertSql.AppendFormat("UPDATEitemcontractpriceASpINNERJOINforeigncurrencyASfONp.ForeignCurrencyId=f.ContractPriceIdSETp.RemainPrice=f.RemainPrice*{0},p.BuyOutPrice=f.BuyOutPrice*{0},p.ReservedPrice=f.ReservedPrice*{0},p.CollectedPrice=f.CollectedPrice*{0},p.AccessPrice=f.AccessPrice*{0}WHEREp.CurrencyId={1}ANDp.dateBETWEEN'{2:yyyy-MM-dd}'AND'{3:yyyy-MM-dd}';",rate.ExchangeRate,exchangeRate.CurrencyId,rate.BeginDate,rate.EndDate); updateInsertSql.AppendFormat("INSERTINTO`itemcontractpricelog`(`ContractPriceType`,`ContractPrice`,`FcContractPrice`,`IsExpire`,`LogRemark`,`CreatedByName`,`CreatedById`,`CreatedDate`,`LogTypeId`,`ProviderId`,`StageId`,`Date`,`CurrencyId`,`ContractPriceId`,`StockPattern`,`ItemId`)SELECT0,c.RemainPrice,f.RemainPrice,c.RemainIsExpire,'外币汇率调整,重新计算人民币底价','job',0,NOW(),5,c.ProviderId,c.StageId,c.Date,c.CurrencyId,c.ContractPriceId,0,c.ItemIdFROMitemcontractpriceAScINNERJOINforeigncurrencyASfONc.ForeignCurrencyId=f.ContractPriceIdWHEREc.CurrencyId={0}ANDc.dateBETWEEN'{1:yyyy-MM-dd}'AND'{2:yyyy-MM-dd}';",exchangeRate.CurrencyId,rate.BeginDate,rate.EndDate); updateInsertSql.AppendFormat("INSERTINTO`itemcontractpricelog`(`ContractPriceType`,`ContractPrice`,`FcContractPrice`,`IsExpire`,`LogRemark`,`CreatedByName`,`CreatedById`,`CreatedDate`,`LogTypeId`,`ProviderId`,`StageId`,`Date`,`CurrencyId`,`ContractPriceId`,`StockPattern`,`ItemId`)SELECT1,c.BuyOutPrice,f.BuyOutPrice,c.BuyOutIsExpire,'外币汇率调整,重新计算人民币底价','job',0,NOW(),5,c.ProviderId,c.StageId,c.Date,c.CurrencyId,c.ContractPriceId,0,c.ItemIdFROMitemcontractpriceAScINNERJOINforeigncurrencyASfONc.ForeignCurrencyId=f.ContractPriceIdWHEREc.CurrencyId={0}ANDc.dateBETWEEN'{1:yyyy-MM-dd}'AND'{2:yyyy-MM-dd}';",exchangeRate.CurrencyId,rate.BeginDate,rate.EndDate); updateInsertSql.AppendFormat("INSERTINTO`itemcontractpricelog`(`ContractPriceType`,`ContractPrice`,`FcContractPrice`,`IsExpire`,`LogRemark`,`CreatedByName`,`CreatedById`,`CreatedDate`,`LogTypeId`,`ProviderId`,`StageId`,`Date`,`CurrencyId`,`ContractPriceId`,`StockPattern`,`ItemId`)SELECT2,c.ReservedPrice,f.ReservedPrice,c.ReservedIsExpire,'外币汇率调整,重新计算人民币底价','job',0,NOW(),5,c.ProviderId,c.StageId,c.Date,c.CurrencyId,c.ContractPriceId,0,c.ItemIdFROMitemcontractpriceAScINNERJOINforeigncurrencyASfONc.ForeignCurrencyId=f.ContractPriceIdWHEREc.CurrencyId={0}ANDc.dateBETWEEN'{1:yyyy-MM-dd}'AND'{2:yyyy-MM-dd}';",exchangeRate.CurrencyId,rate.BeginDate,rate.EndDate); updateInsertSql.AppendFormat("INSERTINTO`itemcontractpricelog`(`ContractPriceType`,`ContractPrice`,`FcContractPrice`,`IsExpire`,`LogRemark`,`CreatedByName`,`CreatedById`,`CreatedDate`,`LogTypeId`,`ProviderId`,`StageId`,`Date`,`CurrencyId`,`ContractPriceId`,`StockPattern`,`ItemId`)SELECT3,c.CollectedPrice,f.CollectedPrice,c.CollectedIsExpire,'外币汇率调整,重新计算人民币底价','job',0,NOW(),5,c.ProviderId,c.StageId,c.Date,c.CurrencyId,c.ContractPriceId,0,c.ItemIdFROMitemcontractpriceAScINNERJOINforeigncurrencyASfONc.ForeignCurrencyId=f.ContractPriceIdWHEREc.CurrencyId={0}ANDc.dateBETWEEN'{1:yyyy-MM-dd}'AND'{2:yyyy-MM-dd}';",exchangeRate.CurrencyId,rate.BeginDate,rate.EndDate); updateInsertSql.AppendFormat("INSERTINTO`itemcontractpricelog`(`ContractPriceType`,`ContractPrice`,`FcContractPrice`,`IsExpire`,`LogRemark`,`CreatedByName`,`CreatedById`,`CreatedDate`,`LogTypeId`,`ProviderId`,`StageId`,`Date`,`CurrencyId`,`ContractPriceId`,`StockPattern`,`ItemId`)SELECT4,c.AccessPrice,f.AccessPrice,c.AccessIsExpire,'外币汇率调整,重新计算人民币底价','job',0,NOW(),5,c.ProviderId,c.StageId,c.Date,c.CurrencyId,c.ContractPriceId,0,c.ItemIdFROMitemcontractpriceAScINNERJOINforeigncurrencyASfONc.ForeignCurrencyId=f.ContractPriceIdWHEREc.CurrencyId={0}ANDc.dateBETWEEN'{1:yyyy-MM-dd}'AND'{2:yyyy-MM-dd}';",exchangeRate.CurrencyId,rate.BeginDate,rate.EndDate); //varcurContractPriceList=itemContractPriceList.Where(o=>o.CurrencyId==exchangeRate.CurrencyId&&o.Date>=rate.BeginDate&&o.Date<=rate.EndDate).ToList(); logger.InfoFormat("底价更新和日志sql:{0}",updateInsertSql.ToString()); //if(curContractPriceList.Count==0)continue; inteffctRows=0; using(vartran=UnitOfWorkManager.Begin()) { effctRows=taskRepository.ExecuteSql(updateInsertSql.ToString(),false); tran.Complete(); } logger.InfoFormat("底价更新影响行数:{0}",effctRows);
正常情况下大概20秒钟就ok.
之前是用EF操作,查询出来,要耗时,然后再组装update语句,然后再插入日志(每条数据5条日志),这个网络交互的时间加上数据库连接打开关闭的时间,总的执行时间,大概10多分钟。
用sql语句批量操作,可以说效率提升了40倍,就是大量数据的传输和数据库的处理次数耗时。
所以说,软件开发不是开发完成就行,而是要解决性能上的问题,这才是开发的进阶。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!