• 主页
  • 基础类
  • 应用实例
  • 新技术前沿

这种相关子查询如何优化,优化达人进

yangqidong 2009-12-03 05:21:20

SELECT A.abc,B.def,isnull((SELECT TOP 1 ghi FROM C WHERE C.jkl=B.mno),'') AS pqr
FROM A INNER JOIN B ON A.stu=B.vwx


这是简化的代码,实际的语句包含很多join,很多isnull(子查询)。表数据量很大,执行效率非常低,请优化达人相助
...全文
128 点赞 收藏 17
写回复
17 条回复
icelovey 2009年12月03日
回复 点赞
menggang9801 2009年12月03日
看看
回复 点赞
haitao 2009年12月03日
SELECT A.abc,B.def,isnull((SELECT TOP 1 ghi FROM C WHERE C.jkl=B.mno),'') AS pqr
FROM A INNER JOIN B ON A.stu=B.vwx

一直不习惯在select的输出字段里写一个子查询,
一来觉得这样是不是意味着这个子查询要被执行n遍(n等于记录数)
二来c、b两个的作用域好像。。。。。。。。
下面这样好像中规中矩一些:但是group by的开销可能会比较大
SELECT A.abc,B.def,isnull(C2.ghi2,'') AS pqr
FROM A
INNER JOIN B ON A.stu=B.vwx
left join (SELECT jkl,min(ghi) ghi2 FROM C group by jkl) c2 on C2.jkl=B.mno
回复 点赞
华夏小卒 2009年12月03日
学习
回复 点赞
feixianxxx 2009年12月03日
with cte as
(
select ghi,jkl,rn=ROW_NUMBER() over(PARTITION by jkl order by getdate() )
from c
)
select A.abc,B.def,ck.
from A INNER JOIN B ON A.stu=B.vwx
left join cte c on a.jkl=b.mno
where rn=1
回复 点赞
feixianxxx 2009年12月03日
[Quote=引用 2 楼 garnett_kg 的回复:]
2005
------------------------------
SELECT A.abc,B.def,
isnull(ct.ghi,'') AS pqr
FROM
    A INNER JOIN B ON A.stu=B.vwx
    OUTER APPLY
    (
      SELECT TOP 1 ghi FROM C WHERE c.jkl=B.mno
    )ct

[/Quote]
2005用APPLY 比 子查询效率好很多

其实应该还有更加快的 用 row_number
回复 点赞
ws_hgo 2009年12月03日
[Quote=引用 9 楼 yangqidong 的回复:]
引用 8 楼 haiwer 的回复:
引用 2 楼 garnett_kg 的回复:
2005
------------------------------
SELECT A.abc,B.def,
isnull(ct.ghi,'') AS pqr
FROM
    A INNER JOIN B ON A.stu=B.vwx
    OUTER APPLY
    (
      SELECT TOP 1 ghi FROM C WHERE c.jkl=B.mno
    )ct


推荐这个


测试了一下,并没有很大的提高。
[/Quote]
这样的话
提供下表结构,测试数据
回复 点赞
让你望见影子的墙 2009年12月03日
看看执行计划,哪一块耗费的时间最多。
ctrl+M
回复 点赞
yangqidong 2009年12月03日
[Quote=引用 8 楼 haiwer 的回复:]
引用 2 楼 garnett_kg 的回复:
2005
------------------------------
SELECT A.abc,B.def,
isnull(ct.ghi,'') AS pqr
FROM
    A INNER JOIN B ON A.stu=B.vwx
    OUTER APPLY
    (
      SELECT TOP 1 ghi FROM C WHERE c.jkl=B.mno
    )ct


推荐这个
[/Quote]

测试了一下,并没有很大的提高。
回复 点赞
昵称被占用了 2009年12月03日
[Quote=引用 2 楼 garnett_kg 的回复:]
2005
------------------------------
SELECT A.abc,B.def,
isnull(ct.ghi,'') AS pqr
FROM
    A INNER JOIN B ON A.stu=B.vwx
    OUTER APPLY
    (
      SELECT TOP 1 ghi FROM C WHERE c.jkl=B.mno
    )ct

[/Quote]
推荐这个
回复 点赞
nanuke 2009年12月03日
......
回复 点赞
pt1314917 2009年12月03日
当然加索引肯定是毋庸置疑的。。
回复 点赞
pt1314917 2009年12月03日

--使用case when then end代替isnull,以前曾试过。case...比isnull的效率要高一些。数据越多越明显。
select abc,def,pqr=case when pqr is null then '' else pqr end
from
(SELECT A.abc,B.def,isnull((SELECT TOP 1 ghi FROM C WHERE C.jkl=B.mno),'') AS pqr
FROM A INNER JOIN B ON A.stu=B.vwx)a

或者直接在程序中去转换。减少数据库处理压力。。。


回复 点赞
netcup 2009年12月03日
相关子查询其实效率倒是不错的,但是TOP 1对效率有一定的影响。
想办法不用TOP 1,并且如楼上几位所言,对 4个字段加索引试下。
回复 点赞
dawugui 2009年12月03日


对stu , vmx ,jkl , mno加上索引.
回复 点赞
Garnett_KG 2009年12月03日
2005
------------------------------
SELECT A.abc,B.def,
isnull(ct.ghi,'') AS pqr
FROM
A INNER JOIN B ON A.stu=B.vwx
OUTER APPLY
(
SELECT TOP 1 ghi FROM C WHERE c.jkl=B.mno
)ct
回复 点赞
--小F-- 2009年12月03日
stu vwx 字段加索引
回复 点赞
发动态
发帖子
MS-SQL Server
创建于2007-09-28

1.4w+

社区成员

25.3w+

社区内容

MS-SQL Server相关内容讨论专区
社区公告
暂无公告