如何优化这个sql语句

2019-03-25 13:43|来源: 网路

SELECT     a.type, b.postnature, b.compcode
FROM  职工岗位管理情况表 AS b INNER JOIN 在职职工基本信息表 AS a ON b.name = a.statusname
WHERE   (a.move = '在岗') and  (type IN  (SELECT  name FROM  在职职工基本信息表用工类别维护表)) AND (postnature IN (SELECT  name  FROM   职工岗位性质维护表))

如果数据量很小,希望能做到以上的执行结果。
但是如果数据量大,目前最少已有50000条记录,数据库为sqlserver2005,请问该如何优化sql语句或者如何写这个效果。
问题补充:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
alter proc zgrytj (@username varchar(100),@tablename varchar(50))
as begin
declare
@qycode varchar(100),
@rolename varchar(100),
@gwlb varchar(100),
@gwxz varchar(100),
@rcount int,
@ctotalcount int,
@rtotalcount int,
@rname varchar(50),
@cname varchar(50),
@totalcount int,
@sqlstr nvarchar(4000),
@sqlstrI nvarchar(4000),
@sqlstrII nvarchar(4000)
create table #test(
   rcount int,
   ctotalcount int,
       rtotalcount int,
   rname varchar(50),
   cname varchar(50),
)
select @qycode=b.code  from sys_user a,sys_企业信息表 b
where  a.corporation=b.code and a.username=@username
select @rolename=rolename  from  sys_memberofrole where member=@username
-----------------如果不是系统帐号查询出单条的信息------
if @rolename<>'系统管理员' and @rolename<>'省局领导'
   begin
  --申明游标
declare gwlb CURSOR FOR select name from 在职职工基本信息表用工类别维护表 order by id
--打开游标
open gwlb
fetch from gwlb into @gwlb
WHILE @@FETCH_STATUS = 0
begin
declare gwxz cursor for select name from 职工岗位性质维护表   order by id
open gwxz
fetch from gwxz into @gwxz
WHILE @@FETCH_STATUS = 0
begin      
select @sqlstr='select @a=count(*)  from '+@tablename+' where '+
'  type ='''+@gwlb+''' and postnature='''+@gwxz+''' and compcode='''+@qycode+''''
        select @sqlstrI='select @a=count(*)  from '+@tablename+' where '+
'  type ='''+@gwlb+''' and compcode='''+@qycode+''''
select @sqlstrII='select @a=count(*)  from '+@tablename+' where '+
'  postnature ='''+@gwxz+''' and compcode='''+@qycode+''''
        exec sp_executesql @sqlstr,N'@a int output',@rcount output
        exec sp_executesql @sqlstrI,N'@a int output',@rtotalcount output
        exec sp_executesql @sqlstrII,N'@a int output',@ctotalcount output
insert into #test
values(@rcount,@ctotalcount,@rtotalcount,@gwlb,@gwxz)
fetch  next from gwxz into @gwxz
end
close gwxz
deallocate gwxz
fetch  next from gwlb into @gwlb
end
CLOSE gwlb--关闭游标
DEALLOCATE gwlb--释放游标
select * from #test
end

else
begin
  --申明游标
declare gwlb CURSOR FOR select name from 在职职工基本信息表用工类别维护表 order by id
--打开游标
open gwlb
fetch from gwlb into @gwlb
WHILE @@FETCH_STATUS = 0
begin
declare gwxz cursor for select name from 职工岗位性质维护表   order by id
open gwxz
fetch from gwxz into @gwxz
WHILE @@FETCH_STATUS = 0
begin      
select @sqlstr='select @a=count(*)  from '+@tablename+' where '+
'  type ='''+@gwlb+''' and postnature='''+@gwxz+''''
        select @sqlstrI='select @a=count(*)  from '+@tablename+' where '+
'  type ='''+@gwlb+''''
select @sqlstrII='select @a=count(*)  from '+@tablename+' where '+
'  postnature ='''+@gwxz+''''
        exec sp_executesql @sqlstr,N'@a int output',@rcount output
        exec sp_executesql @sqlstrI,N'@a int output',@rtotalcount output
        exec sp_executesql @sqlstrII,N'@a int output',@ctotalcount output
insert into #test
values(@rcount,@ctotalcount,@rtotalcount,@gwlb,@gwxz)
fetch  next from gwxz into @gwxz
end
close gwxz
deallocate gwxz
fetch  next from gwlb into @gwlb
end
CLOSE gwlb--关闭游标
DEALLOCATE gwlb--释放游标
select * from #test
end
end

按照
SELECT     a.type, b.postnature, b.compcode
FROM  职工岗位管理情况表 AS b
INNER JOIN 在职职工基本信息表 AS a ON b.name = a.statusname
join 在职职工基本信息表用工类别维护表 c on a.type = c.name
join 职工岗位性质维护表 d on b.postnature = d.name
WHERE   (a.move = '在岗') 建好的视图 名为 zgry

之前问的那个sql语句是为了在这个存储过程中调用的动态表或视图.问题I:select count(*),postnature from zgry group by postnature这个语句执行起来都费事.问题II:我不知道存储过程是否也能优化,不知道有什么问题,之前写的一个没执行很快,和这个存储过程差不多,就是动态传入的视图或表的数据量较大。希望能够给与支持。

相关问答

更多
  • 一样的条件,*是最慢的,把所有属性列出来是最好的
  • 试试这个: insert into mt_seal_inst (detect_task_no, bar_code, seal_date, write_date) select 'DETECT_TASK_NO', 'strBarcode', to_char(to_date(detect_date, 'yyyy-mm-dd hh24:mi:ss') + numtodsinterval(3, 'second')), to_char(to_date(detect_date, 'yyyy-mm-dd hh24:mi: ...
  • 假设原来的句子是 select * from t1 where t1.f1 in (select t2.f2 from t2 where t2.f2=xxx) 和你的很类似 你用子查询 很慢 我们现在修改为: select t1.* from t1 ,t2 where t1.f1 = t2.f2 and t2.f2=xxxx 这里使用了关联查询代替了子查询大大提高效率。 其次你可以考虑在表t1.f1上加索引,提高查询速度。
  • select t.* from tb_User t,tb_UserCount t1 where t.Age>50 and t1.count>500 理由:1不用IN的方式查询 2.要把运算最快的条件放前面,如t.Age>50 ,且运算要放在纯数学的等式中100/2=50
  • 楼主 谁告诉你可以这样写啊 两个语句不等价 第二种写法 是隐含了asc码的比较 每个字母都对应一个asc码 这个您应该知道吧
  • 不知道in中的数据是固定的还是从另一个数据库中查到的,如果是固定的,那没有太好办法了,给classid加个索引是必须的。 如果是从另一个数据中查的,如果少量没关系,大量的话直接在in里写上sql语句。
  • sql语句优化[2022-04-27]

    select top 12 * from Product where productID not in (select top 12 productID from Product where (productName like '%2612%' or productID in (select productID from Product_Fitting where suitType like '%2612%')) and isAdjust = 0 and status = 1) and (productNa ...
  • sql语句优化[2022-08-02]

    1.查看链接查询部分是不是键和索引 2.检查d.area_id是不是有索引 3.检查a.alloc_date是不是有索引 4.将Or链接的条件改成union all的方式来查询 5.(可能是关键)to_char(a.alloc_date,'yyyymm')>='200805' 这个函数方式的,改为直接方式的a.alloc_date >= date'2008-05-01' 避免全表扫描 6.(也可能是关键)检查类型一致性,area_id in d.area_id in (17000124,17000125,1 ...
  • case when (select count(1) from latreebak v, laagentgrade u, laagentgrade w where u.gradeid >w.gradeid and u.gradecode=v.agentlastgrade and w.gradecode =v.agentgrade and v.agentcode =a.agentcode)>0 then '降级' else '未降级' end
  • 基本相同,都遵循SQL语言的语法规则。在SQL脚本上两者最大的区别是函数不一样和个别关键字不一样。比如Oracle里没有limit关键字,所以Oracle实现分页比MySQL麻烦。