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

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(子查询)。表数据量很大,执行效率非常低,请优化达人相助
...全文
216 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
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]
这样的话
提供下表结构,测试数据
  • 打赏
  • 举报
回复
看看执行计划,哪一块耗费的时间最多。
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 字段加索引

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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