读书人

怎的提高这语句的效率

发布时间: 2013-01-04 10:04:18 作者: rapoo

怎样提高这语句的效率
本帖最后由 zzxap 于 2012-11-20 17:12:56 编辑 select * from Invoicing_Invoicing where id not in (712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,774,1052,1053,1054,1055,1056,1057,1059,1061,1062,1065,1067,1068,1069,1070,1071,1087,1088,1089,1091,1092,1093,1095,1097,1098,1099,1100,1638,1640,1641,1642,1878,1879,1880,1881,1882,1883,1884,1885,1886) and userid=132

id是作为一串字符传进来的。貌似用不了leftjoin


[解决办法]


select *
from Invoicing_Invoicing
where charindex(','+cast(id as varchar(10))+',',','+'712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,774,1052,1053,1054,1055,1056,1057,1059,1061,1062,1065,1067,1068,1069,1070,1071,1087,1088,1089,1091,1092,1093,1095,1097,1098,1099,1100,1638,1640,1641,1642,1878,1879,1880,1881,1882,1883,1884,1885,1886'+',')>0
and userid=132

[解决办法]
引用:
SQL code?12345select * from Invoicing_Invoicing where charindex(','+cast(id as varchar(10))+',',','+'712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,774,1052,1053,1054……

楼上没考虑的头和尾的问题。。
我发个我自己写的Func吧。

ALTER function [dbo].[Func_Contains]
(
@Source varchar(200),
@Temp varchar(200)
)
returns bit
begin
declare @i int
set @i=0
set @i=charindex(',',@Source)
if(@i<1)
begin
if (@Temp=@Source)
begin
return 1
end
end
else
begin
if(@Temp =substring(@Source,0,charindex(',',@Source)))
return 1
if(charindex(','+@Temp+',',@Source)>0)
return 1
while (charindex(','+@Temp,@Source)>0)
begin
if(@Temp=substring(@Source,0,charindex(',',@Source)))
return 1
set @Source=substring(@Source,charindex(',',@Source)+1,len(@Source))
end
if(@Temp=@Source)
return 1
end
return 0
end


[解决办法]
引用:
引用:引用:
where中先写userid=132,然后再写not in,至于索引,应该不用说了吧。
高手,为什么这样写,可以解释下吗?首先,where的顺序是有严格限定的,从左到右顺序执行,如果userid有索引的话,就会先大面积筛选掉不必要的数据,值剩下132的数据,假设你有1000万数……



见笑了
确实不知道where条件的顺序是否会影响查询的性能,自己随便测试了一下,有不对的地方还望指正,





create table tableTestWhere
(
StaffID int identity(1,1),
Department varchar(50),
Salary decimal(18,3),
age int,
Level varchar(20),
Remark varchar(36)
)

create unique clustered index IX_ID on tableTestWhere(StaffID)


declare @i int
set @i=0
while @i<100000
begin
declare @d varchar(200),@l varchar(10)
--随便搞个部门职位啥的字段
if(@i<3000)
begin
set @d='A'
set @l='X1'
end
else
begin
set @d='B'
set @l='X2'
end
--工资年龄正比,不成听天由命,O(∩_∩)O~
insert into tableTestWhere values (@d,ceiling(10000*rand()),ceiling(40*rand()),@l,newid())
set @i=@i+1;
end



set statistics profile on

--聚集索引条件在前在后,执行计划是一样的
select * from tableTestWhere
where
staffid<100
and remark in ('F4835A18-3859-4218-990D-1AAC2847AC54','EE9391EB-FD3B-4F38-BFBA-CFEC65AD7828')

--select * from tableTestWhere where remark in ('F4835A18-3859-4218-990D-1AAC2847AC54','EE9391EB-FD3B-4F38-BFBA-CFEC65AD7828') and staffid<100

[解决办法]
--Clustered Index Seek(OBJECT:([DEVTEST].[dbo].[tableTestWhere].[IX_ID]), SEEK:([DEVTEST].[dbo].[tableTestWhere].[StaffID] < (100)), WHERE:([DEVTEST].[dbo].[tableTestWhere].[Remark]='EE9391EB-FD3B-4F38-BFBA-CFEC65AD7828' OR [DEVTEST].[dbo].[tableTestWhere].[Remark]='F4835A18-3859-4218-990D-1AAC2847AC54') ORDERED FORWARD)


select * from tableTestWhere
where
remark in ('F4835A18-3859-4218-990D-1AAC2847AC54','EE9391EB-FD3B-4F38-BFBA-CFEC65AD7828')
and staffid<100

--select * from tableTestWhere where staffid<100 and remark in ('F4835A18-3859-4218-990D-1AAC2847AC54','EE9391EB-FD3B-4F38-BFBA-CFEC65AD7828')

[解决办法]
--Clustered Index Seek(OBJECT:([DEVTEST].[dbo].[tableTestWhere].[IX_ID]), SEEK:([DEVTEST].[dbo].[tableTestWhere].[StaffID] < (100)), WHERE:([DEVTEST].[dbo].[tableTestWhere].[Remark]='EE9391EB-FD3B-4F38-BFBA-CFEC65AD7828' OR [DEVTEST].[dbo].[tableTestWhere].[Remark]='F4835A18-3859-4218-990D-1AAC2847AC54') ORDERED FORWARD)

读书人网 >SQL Server

热点推荐