数据集运行太慢了,经理让我优化,数据库是sqlserver,请教

新建文本文档 (2).zip

WorkBook17 (1).zip

image.png

百煮味香 发布于 2022-5-11 09:36
1min目标场景问卷 立即参与
回答问题
悬赏:3 F币 + 添加悬赏
提示:增加悬赏、完善问题、追问等操作,可使您的问题被置顶,并向所有关注者发送通知
共4回答
最佳回答
0
shinger@126.comLv2见习互助
发布于2022-5-11 11:19(编辑于 2022-5-11 11:43)

如果只是千万级的业务表,用存储过程来实现。在存储过程中多利用临时表,创建好索引,效率并不低。MYSQL超过千万级的数据,还是采取ETL方案吧,数据用定时任务预先汇总好存入数据仓库,报表直接从数据仓库拿数据,而不从业务表拿。我还以为是MYSQL,MSSQL优化这个很简单的。

set nocount on 

declare @starttime datetime,@endtime datetime

set @starttime='${tstart1}'

set @endtime='${tend1}',' 23:59:59.997'

--今年的数据

if object_id('tempdb..#t1') is not null drop table #t1

select cast(o.created as date) orderTime,o.province,o.city,count(o.city) num

   into #t1

 from [order] o join shop sh on o.shop_id=sh.id 

 where o.created between @starttime and @endtime

 /*and o.status=99 订单完成*/

 and pay_status=2 /*支付成功*/

 group by cast(o.created as date),o.province,o.city

--去年的数据

set @starttime=dateadd(year,-1,@starttime)

set @endtime=dateadd(year,-1,@endtime)

if object_id('tempdb..#t2') is not null drop table #t2

select cast(dateadd(year,-1,o.created) as date) orderTime,o.province,o.city,count(o.city) num

   into #t2

 from [order] o join shop sh on o.shop_id=sh.id 

 where o.created between @starttime and @endtime

 /*and o.status=99 订单完成*/

 and pay_status=2 /*支付成功*/

 group by cast(dateadd(year,-1,o.created) as date),o.province,o.city

--临时表创建索引

create index ix_#t1 on #t1 (orderTime,province,city)

create index ix_#t2 on #t2 (orderTime,province,city)

--历史数据的num要给别名,否则帆软分不出你的num是今年的还是去年的数据

select #t1.orderTime,#t1.province,#t1.city,#t1.num,isnull(#t2.num) hisnum,

     case when #t2.num=0 then 1 else  #t1.num*1.00/#t2.num -1 end as 同比

   from #t1 left join #t2 on #t1.orderTime=#t2.orderTime 

          and #t1.province=#t2.province

  and #t1.city=#t2.city

set nocount off

order表里面,最好要有索引,索引要覆盖created 和status,pay_status,shop表有没有索引无所谓,因为这个表数据量并不大。然后看你的代码,并没有对店铺过滤,意味着这个查询其实是找所有店铺的数据,所以最重要的,还是最起码要有created 

最佳回答
0
用户6NWif5139660Lv6资深互助
发布于2022-5-11 09:40
最佳回答
0
CD20160914Lv8专家互助
发布于2022-5-11 09:41(编辑于 2022-5-11 09:46)

子查询里面不要排序。。。。排序就放在最外面了。

还有你的表像shop_id与id字段分别有索引没有?

还有自己查询执行计划吧。。看到底哪一部分慢了。就优化哪一部分

SQL Server执行计划 - 大树2 - 博客园 (cnblogs.com)

还有像条件限制直接写在里面吧,不要写在子查询的外面。。。如果你的表数据量特别的大。。那么如果实时要求不高的情况下。建议做数据etl同步,把所有的数据放在一张表里面,然后查询这一张表就行了。

image.png

  • 百煮味香 百煮味香(提问者) 没有索引o(╥﹏╥)o
    2022-05-11 09:51 
  • CD20160914 CD20160914 回复 百煮味香(提问者) 你先分别查一下订单表有多少行数据。再看一下shop有多少行数据。生产上的数据。。分别有多少行。。然后看一下订单表里面有哪一些索引了?或者你是否有权限对订单表创建索引。。
    2022-05-11 09:53 
最佳回答
0
yzm339714Lv6中级互助
发布于2022-5-11 09:44

用定时任务,把查询的数据固化到一个表里面把,然后每次直接查这个表,或者搞一个多维度的宽表,也是定时作业更新这个表的数据,每次从这个表取数据,多维度的宽表的好处在于设计好的话可以通用,大大的提升了效率

  • 5关注人数
  • 375浏览人数
  • 最后回答于:2022-5-11 11:43
    请选择关闭问题的原因
    确定 取消
    返回顶部