sql优化 感觉这条sql应该能写的很简单 但是 个人能力有限 写成了这个样子 有没有大神能帮我改一下

without_bont 2017-07-25 03:19:36
select rule_id,ruleset_id,rulename,setnote,count(1) as sl,sum(t.yl_dj) as zj,sum(cast( yl_sl as NUMERIC(38,2))) as yl_sl,sum(cast( yl_sfe as NUMERIC(38,2))) as yl_sfe from(
select top 100 percent yl_dj from (
select ck.RULESET_ID,(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,(case when r.name is null then ru.name else r.name end)as rulename,s.note as setnote,ck.yl_wg,yl_sl,yl_sfe from [ztb1010_1000_Y_2_1004] ck left join [ruleset] s on s.id = ck.ruleset_id left join [rules] r on r.id = s.rule_id left join [rules] ru on ru.id = ck.ruleset_id where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f')
union all
select ck.RULESET_ID,(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,(case when r.name is null then ru.name else r.name end)as rulename,s.note as setnote,ck.yl_wg,yl_sl,yl_sfe from [ztb1010_1001_Y_2_1004] ck left join [ruleset] s on s.id = ck.ruleset_id left join [rules] r on r.id = s.rule_id left join [rules] ru on ru.id = ck.ruleset_id where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f')
union all
select ck.RULESET_ID,(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,(case when r.name is null then ru.name else r.name end)as rulename,s.note as setnote,ck.yl_wg,yl_sl,yl_sfe from [ztb1010_1002_Y_2_1004] ck left join [ruleset] s on s.id = ck.ruleset_id left join [rules] r on r.id = s.rule_id left join [rules] ru on ru.id = ck.ruleset_id where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'))z where yl_wg=0) t,
(select ck.RULESET_ID,(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,(case when r.name is null then ru.name else r.name end)as rulename,s.note as setnote,ck.yl_wg,yl_sl,yl_sfe from [ztb1010_1000_Y_2_1004] ck left join [ruleset] s on s.id = ck.ruleset_id left join [rules] r on r.id = s.rule_id left join [rules] ru on ru.id = ck.ruleset_id where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f')
union all
select ck.RULESET_ID,(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,(case when r.name is null then ru.name else r.name end)as rulename,s.note as setnote,ck.yl_wg,yl_sl,yl_sfe from [ztb1010_1001_Y_2_1004] ck left join [ruleset] s on s.id = ck.ruleset_id left join [rules] r on r.id = s.rule_id left join [rules] ru on ru.id = ck.ruleset_id where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f')
union all
select ck.RULESET_ID,(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,(case when r.name is null then ru.name else r.name end)as rulename,s.note as setnote,ck.yl_wg,yl_sl,yl_sfe from [ztb1010_1002_Y_2_1004] ck left join [ruleset] s on s.id = ck.ruleset_id left join [rules] r on r.id = s.rule_id left join [rules] ru on ru.id = ck.ruleset_id where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'))y group by rule_id,ruleset_id,rulename,setnote order by rule_id,ruleset_id
...全文
389 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
without_bont 2017-08-02
  • 打赏
  • 举报
回复
引用 21 楼 appetizing_fish1 的回复:
[quote=引用 20 楼 without_bont 的回复:] [quote=引用 19 楼 appetizing_fish1 的回复:] [quote=引用 18 楼 without_bont 的回复:] [quote=引用 14 楼 appetizing_fish1 的回复:] 先将数据存入临时表, 然后针对 ID, ruleset_id 建聚族索引看看.
聚集索引不是创表的时候自动创建的么? 不是太懂[/quote] 不知你具体数据情况怎样, 如果你临时表查出的数据有唯一性, 那就可以创建,比如 alter table #Tmp_ylsf_b add constraint PK_#Tmp_ylsf_b primary key clustered (rule_id,ruleset_id) [/quote] 假设我创建了聚集索引 那不是需要把它当做查询条件才能加快查询速度么 但是我插入表里的数据我是全部都要啊 所以感觉没什么影响啊[/quote] 因为之前你说了那段代码速度正常, 那你先用临时表代替代码写出来看看, 不要用动态SQL, 这样方便看问题. [/quote] 感觉好麻烦 谢了 我决定换个写法
顺势而为1 2017-08-01
  • 打赏
  • 举报
回复
引用 18 楼 without_bont 的回复:
[quote=引用 14 楼 appetizing_fish1 的回复:] 先将数据存入临时表, 然后针对 ID, ruleset_id 建聚族索引看看.
聚集索引不是创表的时候自动创建的么? 不是太懂[/quote] 不知你具体数据情况怎样, 如果你临时表查出的数据有唯一性, 那就可以创建,比如 alter table #Tmp_ylsf_b add constraint PK_#Tmp_ylsf_b primary key clustered (rule_id,ruleset_id)
without_bont 2017-08-01
  • 打赏
  • 举报
回复
引用 14 楼 appetizing_fish1 的回复:
先将数据存入临时表, 然后针对 ID, ruleset_id 建聚族索引看看.
聚集索引不是创表的时候自动创建的么? 不是太懂
without_bont 2017-08-01
  • 打赏
  • 举报
回复
引用 12 楼 z10843087 的回复:
@without_bont 你现在是怎么改的 语句发来看下
create table #Tmp_ylsf_b ( rule_id varchar(200), ruleset_id varchar(200), rulename varchar(200), setnote varchar(200), yl_dj DECIMAL(18,2), yl_wg decimal(18,2), yl_sl decimal(18,2), yl_sfe decimal(18,2), yl_mzh VARCHAR(200) ) SET @sqldemo = 'INSERT INTO #Tmp_ylsf_b(rule_id,ruleset_id,rulename,setnote, yl_dj,yl_wg,yl_sl,yl_sfe,yl_mzh) select rule_id,ruleset_id,rulename,setnote, yl_dj,yl_wg,yl_sl,yl_sfe,yl_mzh from '+@origin_tb+' as a' EXEC(@sqldemo) SET @sqldemo='select rule_id,ruleset_id,rulename,setnote,count(yl_mzh) as sl,sum(t.yl_dj) as zj'+@result_tb+' from(select top 100 percent yl_dj from #Tmp_ylsf_b z where yl_wg=0) t,#Tmp_ylsf_b y group by rule_id,ruleset_id,rulename,setnote order by rule_id,ruleset_id' EXEC(@sqldemo) SELECT * from #Tmp_ylsf_b END 水平有限 代码不怎么样 帮我看下 大神
without_bont 2017-08-01
  • 打赏
  • 举报
回复
引用 15 楼 appetizing_fish1 的回复:
这段代码速度怎么样, 如果慢, 那应是你的原始表没建好索引, 如果快, 那这段代码应建成临时表, 再建索引.


                    select ck.RULESET_ID,
							(case when r.id is null then ru.id else r.id end)as rule_id,
							ck.yl_dj,
							(case when r.name is null then ru.name else r.name end)as rulename,
							s.note as setnote,ck.yl_wg,yl_sl,yl_sfe 
					from [ztb1010_1000_Y_2_1004] ck  
					left join [ruleset] s on s.id = ck.ruleset_id  
					left join [rules] r on r.id = s.rule_id  
					left join [rules] ru on ru.id = ck.ruleset_id  
					where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f') 
												
					union all 

					select ck.RULESET_ID,
							(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,
							(case when r.name is null then ru.name else r.name end)as rulename,
							s.note as setnote,ck.yl_wg,yl_sl,yl_sfe 
					from [ztb1010_1001_Y_2_1004] ck  
					left join [ruleset] s on s.id = ck.ruleset_id  
					left join [rules] r on r.id = s.rule_id  
					left join [rules] ru on ru.id = ck.ruleset_id  
					where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f') 

					union all 

					select ck.RULESET_ID,
							(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,
							(case when r.name is null then ru.name else r.name end)as rulename,
							s.note as setnote,ck.yl_wg,yl_sl,yl_sfe 
					from [ztb1010_1002_Y_2_1004] ck  
					left join [ruleset] s on s.id = ck.ruleset_id  
					left join [rules] r on r.id = s.rule_id  
					left join [rules] ru on ru.id = ck.ruleset_id  
					where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f')



我就是把这段代码建成临时表了 这段代码速度还行 但是建了临时表再查 整个代码的速度并没有改善 create table #Tmp_ylsf_b ( rule_id varchar(200), ruleset_id varchar(200), rulename varchar(200), setnote varchar(200), yl_dj DECIMAL(18,2), yl_wg decimal(18,2), yl_sl decimal(18,2), yl_sfe decimal(18,2), yl_mzh VARCHAR(200) ) SET @sqldemo = 'INSERT INTO #Tmp_ylsf_b(rule_id,ruleset_id,rulename,setnote, yl_dj,yl_wg,yl_sl,yl_sfe,yl_mzh) select rule_id,ruleset_id,rulename,setnote, yl_dj,yl_wg,yl_sl,yl_sfe,yl_mzh from '+@origin_tb+' as a' EXEC(@sqldemo) SET @sqldemo='select rule_id,ruleset_id,rulename,setnote,count(yl_mzh) as sl,sum(t.yl_dj) as zj'+@result_tb+' from(select top 100 percent yl_dj from #Tmp_ylsf_b z where yl_wg=0) t,#Tmp_ylsf_b y group by rule_id,ruleset_id,rulename,setnote order by rule_id,ruleset_id' EXEC(@sqldemo) SELECT * from #Tmp_ylsf_b END 这个是我创建的临时表 参数是传进来的sql就是我发帖子你上面粘的代码 是不是我有哪个地方写的有问题?
顺势而为1 2017-08-01
  • 打赏
  • 举报
回复
这段代码速度怎么样, 如果慢, 那应是你的原始表没建好索引, 如果快, 那这段代码应建成临时表, 再建索引.


                    select ck.RULESET_ID,
							(case when r.id is null then ru.id else r.id end)as rule_id,
							ck.yl_dj,
							(case when r.name is null then ru.name else r.name end)as rulename,
							s.note as setnote,ck.yl_wg,yl_sl,yl_sfe 
					from [ztb1010_1000_Y_2_1004] ck  
					left join [ruleset] s on s.id = ck.ruleset_id  
					left join [rules] r on r.id = s.rule_id  
					left join [rules] ru on ru.id = ck.ruleset_id  
					where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f') 
												
					union all 

					select ck.RULESET_ID,
							(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,
							(case when r.name is null then ru.name else r.name end)as rulename,
							s.note as setnote,ck.yl_wg,yl_sl,yl_sfe 
					from [ztb1010_1001_Y_2_1004] ck  
					left join [ruleset] s on s.id = ck.ruleset_id  
					left join [rules] r on r.id = s.rule_id  
					left join [rules] ru on ru.id = ck.ruleset_id  
					where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f') 

					union all 

					select ck.RULESET_ID,
							(case when r.id is null then ru.id else r.id end)as rule_id,ck.yl_dj,
							(case when r.name is null then ru.name else r.name end)as rulename,
							s.note as setnote,ck.yl_wg,yl_sl,yl_sfe 
					from [ztb1010_1002_Y_2_1004] ck  
					left join [ruleset] s on s.id = ck.ruleset_id  
					left join [rules] r on r.id = s.rule_id  
					left join [rules] ru on ru.id = ck.ruleset_id  
					where 1=1 and (r.id = '8b8b8bd45b235a35015b23735135001f' or ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f')



顺势而为1 2017-08-01
  • 打赏
  • 举报
回复
先将数据存入临时表, 然后针对 ID, ruleset_id 建聚族索引看看.
zbdzjx 2017-08-01
  • 打赏
  • 举报
回复
1、“select top 100 percent yl_dj from”这段中的“top 100 percent”用处? 2、“select top 100 percent yl_dj from (......)z where yl_wg=0”这段,子查询z中,应该不用查那么多的列,只要yl_dj和yl_wg两列就可以了。你也可以试一下,将where yl_wg=0放到子查询z中,结果是不是一样的。 3、子查询t和子查询y,分别分返回几条记录?如果每个子查询都是返回多条记录,那最终结果会翻倍吧。
顺势而为1 2017-08-01
  • 打赏
  • 举报
回复
引用 20 楼 without_bont 的回复:
[quote=引用 19 楼 appetizing_fish1 的回复:] [quote=引用 18 楼 without_bont 的回复:] [quote=引用 14 楼 appetizing_fish1 的回复:] 先将数据存入临时表, 然后针对 ID, ruleset_id 建聚族索引看看.
聚集索引不是创表的时候自动创建的么? 不是太懂[/quote] 不知你具体数据情况怎样, 如果你临时表查出的数据有唯一性, 那就可以创建,比如 alter table #Tmp_ylsf_b add constraint PK_#Tmp_ylsf_b primary key clustered (rule_id,ruleset_id) [/quote] 假设我创建了聚集索引 那不是需要把它当做查询条件才能加快查询速度么 但是我插入表里的数据我是全部都要啊 所以感觉没什么影响啊[/quote] 因为之前你说了那段代码速度正常, 那你先用临时表代替代码写出来看看, 不要用动态SQL, 这样方便看问题.
without_bont 2017-08-01
  • 打赏
  • 举报
回复
引用 19 楼 appetizing_fish1 的回复:
[quote=引用 18 楼 without_bont 的回复:] [quote=引用 14 楼 appetizing_fish1 的回复:] 先将数据存入临时表, 然后针对 ID, ruleset_id 建聚族索引看看.
聚集索引不是创表的时候自动创建的么? 不是太懂[/quote] 不知你具体数据情况怎样, 如果你临时表查出的数据有唯一性, 那就可以创建,比如 alter table #Tmp_ylsf_b add constraint PK_#Tmp_ylsf_b primary key clustered (rule_id,ruleset_id) [/quote] 假设我创建了聚集索引 那不是需要把它当做查询条件才能加快查询速度么 但是我插入表里的数据我是全部都要啊 所以感觉没什么影响啊
OwenZeng_DBA 2017-07-31
  • 打赏
  • 举报
回复
@without_bont 你现在是怎么改的 语句发来看下
without_bont 2017-07-31
  • 打赏
  • 举报
回复
引用 9 楼 sinat_28984567 的回复:
[quote=引用 8 楼 z10843087 的回复:] [quote=引用 7 楼 sinat_28984567 的回复:] [quote=引用 6 楼 z10843087 的回复:] [quote=引用 5 楼 sinat_28984567 的回复:] [quote=引用 2 楼 without_bont 的回复:] [quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) a,(select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) where id<3) b 实际上 就是这样 在SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]这个虚表后面还需要在加一个判断条件 这一段 纯重复 感觉 很拖累 sql的查询速度 有没有什么办法 能省略一些呢[/quote] 可以把这三个表做一个cte的临时表,这样就不用每次每次都union这三个表了,当做一个整体来用,减少join和union的次数[/quote] 想法不错,不过有一点问题,你把前面三个表直接查出来,没有筛选条件,可能性能反而慢。最好是加上筛选条件,然后做出cte
SELECT    *
                      FROM      [ztb1010_1000_Y_2_1004] ck
                                LEFT JOIN [rules] ru ON ru.id = ck.ruleset_id
                      WHERE     1 = 1
                                AND ( r.id = '8b8b8bd45b235a35015b23735135001f'
                                      OR ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'
                                    )
不过逻辑是不是一样的要自己确认下[/quote] 先放到cte里边会比直接连接慢?没注意过,我想放到外边主要是楼主用了两次这个cte里边的东西,然后分别join了一个表,我看大概可以cte join tab1 join tab2 这样写[/quote] 也不是说先放cte比较慢,是说这些表ztb1010_1001_Y_2_1004 ,如果数据量比较大,直接查出所有的数据,可能会影响性能。因为在下面的join里面本身是有筛选条件的,筛选用到了索引的话是很快的。那你全部都查出来,肯定是走的全表扫描。 [/quote] 恩索引这方面没考虑到,确实可能会有这个问题,那这样的话,这单独三个表就拿不出了,除了where ,还有关联的on更是在where之前就可以筛选掉一大部分,还得带着join的表会更好[/quote] 我把数据做成临时表还是很慢 ,不知道怎么改了
xiaoxiangqing 2017-07-28
  • 打赏
  • 举报
回复
这么复杂,只能一条条去试
二月十六 版主 2017-07-27
  • 打赏
  • 举报
回复
引用 8 楼 z10843087 的回复:
[quote=引用 7 楼 sinat_28984567 的回复:] [quote=引用 6 楼 z10843087 的回复:] [quote=引用 5 楼 sinat_28984567 的回复:] [quote=引用 2 楼 without_bont 的回复:] [quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) a,(select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) where id<3) b 实际上 就是这样 在SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]这个虚表后面还需要在加一个判断条件 这一段 纯重复 感觉 很拖累 sql的查询速度 有没有什么办法 能省略一些呢[/quote] 可以把这三个表做一个cte的临时表,这样就不用每次每次都union这三个表了,当做一个整体来用,减少join和union的次数[/quote] 想法不错,不过有一点问题,你把前面三个表直接查出来,没有筛选条件,可能性能反而慢。最好是加上筛选条件,然后做出cte
SELECT    *
                      FROM      [ztb1010_1000_Y_2_1004] ck
                                LEFT JOIN [rules] ru ON ru.id = ck.ruleset_id
                      WHERE     1 = 1
                                AND ( r.id = '8b8b8bd45b235a35015b23735135001f'
                                      OR ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'
                                    )
不过逻辑是不是一样的要自己确认下[/quote] 先放到cte里边会比直接连接慢?没注意过,我想放到外边主要是楼主用了两次这个cte里边的东西,然后分别join了一个表,我看大概可以cte join tab1 join tab2 这样写[/quote] 也不是说先放cte比较慢,是说这些表ztb1010_1001_Y_2_1004 ,如果数据量比较大,直接查出所有的数据,可能会影响性能。因为在下面的join里面本身是有筛选条件的,筛选用到了索引的话是很快的。那你全部都查出来,肯定是走的全表扫描。 [/quote] 恩索引这方面没考虑到,确实可能会有这个问题,那这样的话,这单独三个表就拿不出了,除了where ,还有关联的on更是在where之前就可以筛选掉一大部分,还得带着join的表会更好
OwenZeng_DBA 2017-07-27
  • 打赏
  • 举报
回复
引用 7 楼 sinat_28984567 的回复:
[quote=引用 6 楼 z10843087 的回复:] [quote=引用 5 楼 sinat_28984567 的回复:] [quote=引用 2 楼 without_bont 的回复:] [quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) a,(select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) where id<3) b 实际上 就是这样 在SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]这个虚表后面还需要在加一个判断条件 这一段 纯重复 感觉 很拖累 sql的查询速度 有没有什么办法 能省略一些呢[/quote] 可以把这三个表做一个cte的临时表,这样就不用每次每次都union这三个表了,当做一个整体来用,减少join和union的次数[/quote] 想法不错,不过有一点问题,你把前面三个表直接查出来,没有筛选条件,可能性能反而慢。最好是加上筛选条件,然后做出cte
SELECT    *
                      FROM      [ztb1010_1000_Y_2_1004] ck
                                LEFT JOIN [rules] ru ON ru.id = ck.ruleset_id
                      WHERE     1 = 1
                                AND ( r.id = '8b8b8bd45b235a35015b23735135001f'
                                      OR ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'
                                    )
不过逻辑是不是一样的要自己确认下[/quote] 先放到cte里边会比直接连接慢?没注意过,我想放到外边主要是楼主用了两次这个cte里边的东西,然后分别join了一个表,我看大概可以cte join tab1 join tab2 这样写[/quote] 也不是说先放cte比较慢,是说这些表ztb1010_1001_Y_2_1004 ,如果数据量比较大,直接查出所有的数据,可能会影响性能。因为在下面的join里面本身是有筛选条件的,筛选用到了索引的话是很快的。那你全部都查出来,肯定是走的全表扫描。
二月十六 版主 2017-07-27
  • 打赏
  • 举报
回复
引用 6 楼 z10843087 的回复:
[quote=引用 5 楼 sinat_28984567 的回复:] [quote=引用 2 楼 without_bont 的回复:] [quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) a,(select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) where id<3) b 实际上 就是这样 在SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]这个虚表后面还需要在加一个判断条件 这一段 纯重复 感觉 很拖累 sql的查询速度 有没有什么办法 能省略一些呢[/quote] 可以把这三个表做一个cte的临时表,这样就不用每次每次都union这三个表了,当做一个整体来用,减少join和union的次数[/quote] 想法不错,不过有一点问题,你把前面三个表直接查出来,没有筛选条件,可能性能反而慢。最好是加上筛选条件,然后做出cte
SELECT    *
                      FROM      [ztb1010_1000_Y_2_1004] ck
                                LEFT JOIN [rules] ru ON ru.id = ck.ruleset_id
                      WHERE     1 = 1
                                AND ( r.id = '8b8b8bd45b235a35015b23735135001f'
                                      OR ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'
                                    )
不过逻辑是不是一样的要自己确认下[/quote] 先放到cte里边会比直接连接慢?没注意过,我想放到外边主要是楼主用了两次这个cte里边的东西,然后分别join了一个表,我看大概可以cte join tab1 join tab2 这样写
OwenZeng_DBA 2017-07-27
  • 打赏
  • 举报
回复
引用 5 楼 sinat_28984567 的回复:
[quote=引用 2 楼 without_bont 的回复:] [quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) a,(select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) where id<3) b 实际上 就是这样 在SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]这个虚表后面还需要在加一个判断条件 这一段 纯重复 感觉 很拖累 sql的查询速度 有没有什么办法 能省略一些呢[/quote] 可以把这三个表做一个cte的临时表,这样就不用每次每次都union这三个表了,当做一个整体来用,减少join和union的次数[/quote] 想法不错,不过有一点问题,你把前面三个表直接查出来,没有筛选条件,可能性能反而慢。最好是加上筛选条件,然后做出cte
SELECT    *
                      FROM      [ztb1010_1000_Y_2_1004] ck
                                LEFT JOIN [rules] ru ON ru.id = ck.ruleset_id
                      WHERE     1 = 1
                                AND ( r.id = '8b8b8bd45b235a35015b23735135001f'
                                      OR ck.ruleset_id = '8b8b8bd45b235a35015b23735135001f'
                                    )
不过逻辑是不是一样的要自己确认下
二月十六 版主 2017-07-27
  • 打赏
  • 举报
回复
引用 2 楼 without_bont 的回复:
[quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) a,(select * from (SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]) where id<3) b 实际上 就是这样 在SELECT * FROM [ztb1010_1000_Y_2_1004] UNION SELECT * FROM [ztb1010_1001_Y_2_1004] UNION SELECT * FROM [ztb1010_1002_Y_2_1004]这个虚表后面还需要在加一个判断条件 这一段 纯重复 感觉 很拖累 sql的查询速度 有没有什么办法 能省略一些呢[/quote] 可以把这三个表做一个cte的临时表,这样就不用每次每次都union这三个表了,当做一个整体来用,减少join和union的次数
without_bont 2017-07-27
  • 打赏
  • 举报
回复
引用 3 楼 shiguangxin 的回复:
[quote=引用 1 楼 sinat_28984567 的回复:] 太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
我觉sinat_28984567 说得有道理 你可以CTRL+L 对比 一下执行计划[/quote] 额 水平有限 能不能说的明白点
shiguangxin 2017-07-26
  • 打赏
  • 举报
回复
引用 1 楼 sinat_28984567 的回复:
太长了看不太清楚……楼主看看这样能不能简化
;WITH cte AS (
SELECT * FROM [ztb1010_1000_Y_2_1004]
UNION 
SELECT * FROM [ztb1010_1001_Y_2_1004]
UNION
SELECT * FROM [ztb1010_1002_Y_2_1004]
)
SELECT 聚合操作之类的读取  FROM cte LEFT JOIN tab1 ON .....LEFT JOIN tab2 ON ....
我觉sinat_28984567 说得有道理 你可以CTRL+L 对比 一下执行计划
加载更多回复(2)

34,587

社区成员

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

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