sql 多个表连接 查询速度慢

holicc 2012-08-10 12:16:48
我最近在优化sql语句,这里碰到了棘手的问题,多个表连接,我把连接的字段都建立了索引,每个表的数据在10w左右。运行我的代码后,sql执行是9s;这个时间太慢了,能否有更好的提升空间?
下面把代码贴出:
select row_number() over (order by b.applicationmainCode desc) as rowid, 
a.applicationdetailid,a.ApplicationMainCode,a.price,a.goodsnum,a.reciveNum,a.sendNum,a.PublicNum,
a.Currency,a.equipment,a.equipmentnum,a.requiredate,a.des,
c.suppliername,d.goodsname,d.standard, d.unit,d.productid,
d.productArea,d.buyarea,e.paymenter,f.workunit,g.classname,
b.Ausername,b.AworkUnit,b.applicationMaindate,b.buycode,UseProuduct,
ProductCode,TSort,TsortChild,TSortNum,
case when tnewflag=1 then '新' else '旧' end as tnewStatus,Tcontent,Tdes,d.price as GPrice ,
case when b.comfigflag=0 then '是' else '否' end as comfigstatus,
(select top 1 getgoodsdate from instock where applicationdetailid=a.applicationdetailid order by getgoodsdate) as getgoodsdate
from Gr_dt_applicationDetail a left join Gr_db_supplier c on a.supplierid=c.supplierid
left join applicationMain b on a.applicationmainCode=b.ApplicationMaincode
left join goods d on a.goodsid=d.goodsid
left join Payment e on b.paymentid=e.paymentid
left join workunit f on b.UworkUnitId=f.workUnit_Id
left join goodstreeclass g on b.classid=g.classid
where a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid
and 1=1 and b.passflag>=1
order by b.applicationmainCode desc

查看了执行计划,就是order by b.applicationmaincode 消耗25%的;其他的都很少了;有没有更好的方法解决,争取速度的提升到1s之内。
...全文
1725 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yeluochengshang 2013-05-23
  • 打赏
  • 举报
回复 1
我也碰到这个问题,不知道你的解决了没,我这边查出来的问题,就是2个大数据量的表做连接查询必然耗费很长的时间(N个表就更不用说了),除非可以想办法减少2个做连接的表中的数据量 比如我的case是: select * from t,ut,u where t.tid = ut.tid and ut.uid = u.uid 其中t表和ut表的数据量都在300W的样子 (当初模型设计的问题,ut表根本没必要存在,可以改模型要对整个系统懂大手术) 但是可以通过添加查询条件来减少做表连接的数据量,来提升查询时间 t表有个创建时间,通过创建时间为某一天来查询,查询时间果断<0.1秒了 但是个人觉得问题的源头在于系统的模型设计,模型设计的好了,根本不需要做多表的关联查询
holicc 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
你的语句 ,查出来了多少行呀?

( SELECT TOP 1
getgoodsdate
FROM instock
WHERE applicationdetailid = a.applicationdetailid
ORDER BY getgoodsdate
) AS getgoodsdate
这里的 instock 表,applicationdetaili……
[/Quote]
10w多行……
holicc 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
个人觉得left join用多了。。
[/Quote]
大哥,我看过有的人代码,left join 比我的还多呢……
duoxu1983 2012-08-15
  • 打赏
  • 举报
回复
个人觉得left join用多了。。
弘恩 2012-08-15
  • 打赏
  • 举报
回复
不知道,你用那么多的 LEFT JOIN ?
zhang19920408 2012-08-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

引用 5 楼 的回复:
引用 1 楼 的回复:
LZ where里的"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid"与left join的on条件有冲突。如果你这样写的话,相当于用inner join了,也没必要在where语句写"a.applicationmainCode=b.Application……
[/Quote]
同意9楼的说法
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
引用 1 楼 的回复:
LZ where里的"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid"与left join的on条件有冲突。如果你这样写的话,相当于用inner join了,也没必要在where语句写"a.applicationmainCode=b.ApplicationMaincode and a.……
[/Quote]
最后那个ORDER BY可以去掉了,因为你row_number已经有了
holicc 2012-08-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
引用 5 楼 的回复:
引用 1 楼 的回复:
LZ where里的"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid"与left join的on条件有冲突。如果你这样写的话,相当于用inner join了,也没必要在where语句写"a.applicationmainCode=b.ApplicationMa……
[/Quote]我试了一下,速度没影响,还是那么慢,倒是id号不怎么有序了
  • 打赏
  • 举报
回复
LZ where里的"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid"与left join的on条件有冲突。如果你这样写的话,相当于用inner join了,也没必要在where语句写"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid
"了
弘恩 2012-08-10
  • 打赏
  • 举报
回复
这里的 instock 表,applicationdetailid ,getgoodsdate 有索引没有呀?
弘恩 2012-08-10
  • 打赏
  • 举报
回复
你的语句 ,查出来了多少行呀?

( SELECT TOP 1
getgoodsdate
FROM instock
WHERE applicationdetailid = a.applicationdetailid
ORDER BY getgoodsdate
) AS getgoodsdate
这里的 instock 表,applicationdetailid ,getgoodsdate 有字段没有呀?
holicc 2012-08-10
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
这样的语句,在数据量大,索引没维护好,想不慢都难呀。

通过执行计划检查性能低的位置,再考虑建索引,关联表太多考虑使用临时表。
[/Quote]
用临时表不是更费时间??、
holicc 2012-08-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
LZ where里的"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goodsid"与left join的on条件有冲突。如果你这样写的话,相当于用inner join了,也没必要在where语句写"a.applicationmainCode=b.ApplicationMaincode and a.goodsid=d.goo……
[/Quote]
多谢兄台提点,代码写的有点乱,不过没怎么提速啊……
ORAClE SE 2012-08-10
  • 打赏
  • 举报
回复
大姐,9s不算慢呀!!!!
Andy-W 2012-08-10
  • 打赏
  • 举报
回复
这样的语句,在数据量大,索引没维护好,想不慢都难呀。

通过执行计划检查性能低的位置,再考虑建索引,关联表太多考虑使用临时表。
Mr_Nice 2012-08-10
  • 打赏
  • 举报
回复
SELECT  row_number() OVER ( ORDER BY b.applicationmainCode DESC ) AS rowid ,
a.applicationdetailid ,
a.ApplicationMainCode ,
a.price ,
a.goodsnum ,
a.reciveNum ,
a.sendNum ,
a.PublicNum ,
a.Currency ,
a.equipment ,
a.equipmentnum ,
a.requiredate ,
a.des ,
c.suppliername ,
d.goodsname ,
d.standard ,
d.unit ,
d.productid ,
d.productArea ,
d.buyarea ,
e.paymenter ,
f.workunit ,
g.classname ,
b.Ausername ,
b.AworkUnit ,
b.applicationMaindate ,
b.buycode ,
UseProuduct ,
ProductCode ,
TSort ,
TsortChild ,
TSortNum ,
CASE WHEN tnewflag = 1 THEN '新'
ELSE '旧'
END AS tnewStatus ,
Tcontent ,
Tdes ,
d.price AS GPrice ,
CASE WHEN b.comfigflag = 0 THEN '是'
ELSE '否'
END AS comfigstatus ,
( SELECT TOP 1
getgoodsdate
FROM instock
WHERE applicationdetailid = a.applicationdetailid
ORDER BY getgoodsdate
) AS getgoodsdate
FROM Gr_dt_applicationDetail a
LEFT JOIN Gr_db_supplier c ON a.supplierid = c.supplierid
LEFT JOIN applicationMain b ON a.applicationmainCode = b.ApplicationMaincode
LEFT JOIN goods d ON a.goodsid = d.goodsid --#
LEFT JOIN Payment e ON b.paymentid = e.paymentid
LEFT JOIN workunit f ON b.UworkUnitId = f.workUnit_Id
LEFT JOIN goodstreeclass g ON b.classid = g.classid
WHERE a.applicationmainCode = b.ApplicationMaincode
AND a.goodsid = d.goodsid --这个地方跟#处有点儿重复了,#处改成 inner join
AND 1 = 1
AND b.passflag >= 1
ORDER BY b.applicationmainCode DESC
通过慢sql分析的学习,了解什么是慢sql,以及慢SQL会引起那些性能问题。清楚慢sql日志的设置,然后再通过慢sql分析工具的学习,清楚慢sql分析的步骤和流程。慢sql分析工具:mysqldumpslow工具、explain工具、profile工具、Optimizer Trace工具。 提供课程中所使用的sql语句。 课程内容:第一章:课程简介1、课程介绍2、课程大纲 第二章:慢sql简介1、慢sql简介2、慢sql会引起的问题 第三章:慢日志的设置1、慢sql的分析流程2、慢日志参数理解3、慢日志参数设置:第1种方式:my.ini文件设置4、慢日志参数设置:第2种方式:sql脚本设置5、慢日志参数设置-效果验证 第四章:如何发现慢sql1、如何发现慢sql:第1种方式:慢日志文件2、如何发现慢sql:第2种方式:mysql库的slow_log 第五章:慢sql分析工具1、慢sql提取-mysqldumpslow工具-使用方法2、慢sql提取-mysqldumpslow工具-操作实战3、慢sql的执行计划分析-explain分析-执行计划结果说明4、慢sql的执行计划分析-explain分析-索引介绍+type类型举例5、慢sql的资源开销分析-profile分析-分析步骤6、慢sql的资源开销分析-profile分析-show profile执行阶段说明7、慢sql的资源开销分析-profile分析-完整列说明+操作实战8、慢sql的跟踪分析-Optimizer Trace分析-分析步骤9、慢sql的跟踪分析-Optimizer Trace的介绍10、索引失效场景举例 第六章:慢日志清理1、慢日志清理

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧