sqlserverin使用
A. sqlSERVER语句 in和exists哪个效率高本人测试证明
当in的部分很小,只有原表的10%不到会比较高效,
还要看你内存大小,禅誉in部分会罩培先放到内存里,如果内存放不下那么就会很慢很慢,不停的io交换
事实上如果in部分不能枚举出来我都物袭唯不会用in操作
exists更百搭一点,至少不会太慢
B. 关于sqlserver中存储过程里面in关键字的使用
首先就是@chooseid的问题
如果你这样in的话
即使你的 @chooseid=1,2,3
他也会把这几个看做一个整体
也就是把 id 同 '1,2,3'这个整体去比对
而不是拆开
这样的话只能用动态去构建
declare @sql varchar(1000)
set @sql=''
select @sql='delete from table1 where id in ('+ @chooseid+') and uid='+@uid
exec(@sql)
动态构建 也是可以增加@uid的条件的啊...
不太明白你的意思
你可以把代码写全
肯定是可以动态的
写全了 我给你写
C. SQLSERVER语句 in和exists哪个效率高本人测试证明
相同库结构下,很明显 Exists效率高 in 在字符串下的效率是很低的,
主要原因是索引 如果是INT型,有索引的情况,基本上没太大区别 没有太大数据的情况,基本上不用纠结这些陆睁知东西早消早顷
D. sqlserver数据库,批量更新用in不生效。
这跟你的存储过程有关,明显是传进去的id值拼接成了一个字符串,存储过程没处理,导致存储过程真正执行的sql是这样的↓
select * from tb where id in('1002,5008')
看到没,数据库就认为'1002,5008'这个是一个单独的id
把存储过程的sql打印出来看下你就清楚了。
E. SQLSERVER 2005数据库 IN 操作符 的问题
需粗慧要辅助表
select a.Functionary,isnull(sum(MoneyReceipt),0) as TotalReceipt
from
(select Functionary='111' union all
select '2222' union all
select '3333'并乱union all
select '44444'岩蔽答) a
left join PE_Orders b on a.Functionary=b.Functionary
group by a.functionary
F. SQLSERVER语句 in和exists哪个效率高本人测试证明
例如下面两个SQL语句蠢并
1 SELECT OrderNo, SiteCode, AreaCode
2 FROM SchelingProgram
3 WHERE AreaCode IN ( 'P', 'M' ) AND SiteCode IN ( SELECT SiteCode
4 FROM EnvBasicInfo
5 WHERE cityiD = 31 ) AND OrderNo NOT IN (
6 SELECT OrderNo
7 FROM KK_DeliveryinfoTmp )
上面SQL语句IN里面有IN和NOT IN
1 SELECT OrderNo, SiteCode, AreaCode
2 FROM SchelingProgram
3 WHERE ( AreaCode IN ( 'P', 'M' ) AND SiteCode IN ( SELECT SiteCode
4 FROM EnvBasicInfo
5 WHERE cityiD = 31 )
6 ) AND NOT EXISTS ( SELECT OrderNo
7 FROM KK_DeliveryinfoTmp
8 WHERE KK_DeliveryinfoTmp.OrderNo = SchelingProgram.OrderNo )
上面的SQL语句IN里面又有NOT EXISTS
这样的情况很难测试同等条件下IN语句和EXISTS语句的效率
还有一个非SARG运算符
在《SQLSERVER企业级平台管理实践》的第424页里提到:
SQLSERVER对筛选条件(search argument/SARG)的写法有一定的建议
对于不使用SARG运算符的表达式,索引是没有用的,SQLSERVER对它们很难使用比较优化的做法。非SARG运算符包括
NOT、<>、NOT EXISTS、NOT IN、NOT LIKE和内部函数,例如:Convert、Upper等咐烂
所以当您的表中有索引并且SQL语句包含非SARG运带简迹算符,那么当测试SQL语句的执行时间的时候肯定相差很大,
因为有些SQL语句走索引,有些SQL语句不走索引
建表脚本
注意:两个表中都有索引!!
CT_FuelingData表
1 USE [GPOSDB]
2 GO
3 /****** 对象: Table [dbo].[CT_FuelingData] 脚本日期: 08/24/2013 11:00:34 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 SET ANSI_PADDING ON
9 GO
10 CREATE TABLE [dbo].[CT_FuelingData](
11 [RecordNO] [int] IDENTITY(1,1) NOT NULL,
12 [I_FD_StationNo] [int] NOT NULL,
13 [VC_FD_No] [varchar](50) NOT NULL,
14 [VC_FD_Cardno] [varchar](50) NOT NULL,
15 [I_FD_CardStatus] [int] NULL,
16 [LI_FD_CTC] [bigint] NOT NULL,
17 [I_FD_TypeCode] [int] NULL,
18 [I_FD_PumpID] [int] NOT NULL,
19 [VC_FD_OilType] [varchar](50) NULL,
20 [DE_FD_Volume] [decimal](18, 2) NULL,
21 [DE_FD_Price] [decimal](18, 2) NULL,
22 [DE_FD_Amount] [decimal](18, 2) NULL,
23 [I_FD_Point] [decimal](10, 2) NULL,
24 [D_FD_DateTime] [datetime] NOT NULL,
25 [VC_FD_GroupNo] [varchar](50) NULL,
26 [D_FD_GroupDate] [datetime] NULL,
27 [DE_FD_CardAmount] [decimal](18, 2) NULL,
28 [DE_FD_VolumeTotals] [decimal](18, 2) NULL,
29 [DE_FD_AmountTotals] [decimal](18, 2) NULL,
30 [I_FD_ISSend] [int] NULL,
31 [VC_FD_CardMoneyauthFile] [varchar](50) NULL,
32 [D_Month] [datetime] NULL,
33 CONSTRAINT [PK_CT_FuelingData_1] PRIMARY KEY CLUSTERED
34 (
35 [VC_FD_No] ASC
36 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
37 ) ON [PRIMARY]
38
39 GO
40 SET ANSI_PADDING OFF
CT_InhouseCard表
1 USE [GPOSDB]
2 GO
3 /****** 对象: Table [dbo].[CT_InhouseCard] 脚本日期: 08/24/2013 10:59:58 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 SET ANSI_PADDING ON
9 GO
10 CREATE TABLE [dbo].[CT_InhouseCard](
11 [RecordNO] [int] IDENTITY(1,1) NOT NULL,
12 [VC_IC_CardNO] [varchar](50) NOT NULL,
13 [VC_IC_PhysicalNO] [varchar](50) NULL,
14 [I_IC_CardType] [int] NULL,
15 [VC_IC_UserName] [varchar](50) NULL,
16 [VC_IC_JobNO] [varchar](50) NULL,
17 [VC_IC_UserID] [varchar](50) NULL,
18 [VC_IC_Password] [varchar](50) NULL,
19 [DE_IC_CardAmount] [decimal](18, 2) NULL,
20 [DE_IC_AppendAmount] [decimal](18, 2) NULL,
21 [DE_IC_ConsumerAmount] [decimal](18, 2) NULL,
22 [I_IC_ISLost] [int] NULL,
23 [D_IC_UsedDateTime] [datetime] NULL,
24 [D_IC_UselifeDateTime] [datetime] NULL,
25 [I_IC_IssueStationNO] [int] NULL,
26 [VC_IC_IssuerNO] [varchar](50) NULL,
27 [D_IC_IssueDateTime] [datetime] NULL,
28 [D_IC_LastUpdateDateTime] [datetime] NULL,
29 [I_IC_CardStatus] [int] NULL,
30 [VC_IC_Remark] [varchar](256) NULL,
31 CONSTRAINT [PK_CT_InhouseCard] PRIMARY KEY CLUSTERED
32 (
33 [VC_IC_CardNO] ASC
34 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
35 ) ON [PRIMARY]
36
37 GO
38 SET ANSI_PADDING OFF
G. SQLSERVER语句 in和exists哪个效率高本人测试证明
最近很多人讨燃则论in和exists哪个效率高,今茄段旦天就自己测试一下
我使用的是客户的数据库GPOSDB(已经有数据)
环境:SQLSERVER2005 Windows7
我的测试条件:两个表作连接根据VC_IC_CardNO字段,查出CT_InhouseCard表中的VC_IC_CardNO(卡号)在CT_FuelingData表中存在的记录
前提:某些人可能在SQL语句中有多个in,或者多个exists,这些情况很难测试效率的,因为大家的条件都不相同
例如下面两个SQL语句
1 SELECT OrderNo, SiteCode, AreaCode
2 FROM SchelingProgram
3 WHERE AreaCode IN ( 'P', 'M' ) AND SiteCode IN ( SELECT SiteCode
4 FROM EnvBasicInfo
5 WHERE cityiD = 31 ) AND OrderNo NOT IN (
6 SELECT OrderNo
7 FROM KK_DeliveryinfoTmp )
上面SQL语句颤扰IN里面有IN和NOT IN
1 SELECT OrderNo, SiteCode, AreaCode
2 FROM SchelingProgram
3 WHERE ( AreaCode IN ( 'P', 'M' ) AND SiteCode IN ( SELECT SiteCode
4 FROM EnvBasicInfo
5 WHERE cityiD = 31 )
6 ) AND NOT EXISTS ( SELECT OrderNo
7 FROM KK_DeliveryinfoTmp
8 WHERE KK_DeliveryinfoTmp.OrderNo = SchelingProgram.OrderNo )
上面的SQL语句IN里面又有NOT EXISTS
这样的情况很难测试同等条件下IN语句和EXISTS语句的效率
还有一个非SARG运算符
在《SQLSERVER企业级平台管理实践》的第424页里提到:
SQLSERVER对筛选条件(search argument/SARG)的写法有一定的建议
对于不使用SARG运算符的表达式,索引是没有用的,SQLSERVER对它们很难使用比较优化的做法。非SARG运算符包括
NOT、<>、NOT EXISTS、NOT IN、NOT LIKE和内部函数,例如:Convert、Upper等
所以当您的表中有索引并且SQL语句包含非SARG运算符,那么当测试SQL语句的执行时间的时候肯定相差很大,
因为有些SQL语句走索引,有些SQL语句不走索引
建表脚本
注意:两个表中都有索引!!
CT_FuelingData表
1 USE [GPOSDB]
2 GO
3 /****** 对象: Table [dbo].[CT_FuelingData] 脚本日期: 08/24/2013 11:00:34 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 SET ANSI_PADDING ON
9 GO
10 CREATE TABLE [dbo].[CT_FuelingData](
11 [RecordNO] [int] IDENTITY(1,1) NOT NULL,
12 [I_FD_StationNo] [int] NOT NULL,
13 [VC_FD_No] [varchar](50) NOT NULL,
14 [VC_FD_Cardno] [varchar](50) NOT NULL,
15 [I_FD_CardStatus] [int] NULL,
16 [LI_FD_CTC] [bigint] NOT NULL,
17 [I_FD_TypeCode] [int] NULL,
18 [I_FD_PumpID] [int] NOT NULL,
19 [VC_FD_OilType] [varchar](50) NULL,
20 [DE_FD_Volume] [decimal](18, 2) NULL,
21 [DE_FD_Price] [decimal](18, 2) NULL,
22 [DE_FD_Amount] [decimal](18, 2) NULL,
23 [I_FD_Point] [decimal](10, 2) NULL,
24 [D_FD_DateTime] [datetime] NOT NULL,
25 [VC_FD_GroupNo] [varchar](50) NULL,
26 [D_FD_GroupDate] [datetime] NULL,
27 [DE_FD_CardAmount] [decimal](18, 2) NULL,
28 [DE_FD_VolumeTotals] [decimal](18, 2) NULL,
29 [DE_FD_AmountTotals] [decimal](18, 2) NULL,
30 [I_FD_ISSend] [int] NULL,
31 [VC_FD_CardMoneyauthFile] [varchar](50) NULL,
32 [D_Month] [datetime] NULL,
33 CONSTRAINT [PK_CT_FuelingData_1] PRIMARY KEY CLUSTERED
34 (
35 [VC_FD_No] ASC
36 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
37 ) ON [PRIMARY]
38
39 GO
40 SET ANSI_PADDING OFF
CT_InhouseCard表
1 USE [GPOSDB]
2 GO
3 /****** 对象: Table [dbo].[CT_InhouseCard] 脚本日期: 08/24/2013 10:59:58 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 SET ANSI_PADDING ON
9 GO
10 CREATE TABLE [dbo].[CT_InhouseCard](
11 [RecordNO] [int] IDENTITY(1,1) NOT NULL,
12 [VC_IC_CardNO] [varchar](50) NOT NULL,
13 [VC_IC_PhysicalNO] [varchar](50) NULL,
14 [I_IC_CardType] [int] NULL,
15 [VC_IC_UserName] [varchar](50) NULL,
16 [VC_IC_JobNO] [varchar](50) NULL,
17 [VC_IC_UserID] [varchar](50) NULL,
18 [VC_IC_Password] [varchar](50) NULL,
19 [DE_IC_CardAmount] [decimal](18, 2) NULL,
20 [DE_IC_AppendAmount] [decimal](18, 2) NULL,
21 [DE_IC_ConsumerAmount] [decimal](18, 2) NULL,
22 [I_IC_ISLost] [int] NULL,
23 [D_IC_UsedDateTime] [datetime] NULL,
24 [D_IC_UselifeDateTime] [datetime] NULL,
25 [I_IC_IssueStationNO] [int] NULL,
26 [VC_IC_IssuerNO] [varchar](50) NULL,
27 [D_IC_IssueDateTime] [datetime] NULL,
28 [D_IC_LastUpdateDateTime] [datetime] NULL,
29 [I_IC_CardStatus] [int] NULL,
30 [VC_IC_Remark] [varchar](256) NULL,
31 CONSTRAINT [PK_CT_InhouseCard] PRIMARY KEY CLUSTERED
32 (
33 [VC_IC_CardNO] ASC
34 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
35 ) ON [PRIMARY]
36
37 GO
38 SET ANSI_PADDING OFF
测试脚本
因为这个是客户的数据库,本来里面已经有数据了,所以在测试之前先更新两个表的统计信息,以做到公正
1 USE [GPOSDB]
2 GO
3 UPDATE STATISTICS CT_FuelingData
4 UPDATE STATISTICS CT_InhouseCard
5 GO
IN语句
1 USE [GPOSDB]
2 GO
3 DBCC DROPCLEANBUFFERS
4 GO
5 DBCC FREEPROCCACHE
6 GO
7 SET STATISTICS IO ON
8 GO
9 SET STATISTICS TIME ON
10 GO
11 SET STATISTICS PROFILE ON
12 GO
13 SELECT * FROM [dbo].[CT_FuelingData] WHERE [VC_FD_Cardno] IN (SELECT [VC_IC_CardNO] FROM [dbo].[CT_InhouseCard])
EXISTS语句
1 USE [GPOSDB]
2 GO
3 DBCC DROPCLEANBUFFERS
4 GO
5 DBCC FREEPROCCACHE
6 GO
7 SET STATISTICS IO ON
8 GO
9 SET STATISTICS TIME ON
10 GO
11 SET STATISTICS PROFILE ON
12 GO
13 SELECT *
14 FROM [dbo].[CT_FuelingData]
15 WHERE EXISTS ( SELECT [VC_IC_CardNO]
16 FROM [dbo].[CT_InhouseCard]
17 WHERE [dbo].[CT_FuelingData].[VC_FD_Cardno] = [dbo].[CT_InhouseCard].[VC_IC_CardNO] )
测试结果
IN语句
1 SQL Server 执行时间:
2 CPU 时间 = 0 毫秒,占用时间 = 2 毫秒。
3 SQL Server 分析和编译时间:
4 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
5
6 SQL Server 执行时间:
7 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
8 SQL Server 分析和编译时间:
9 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
10
11 SQL Server 执行时间:
12 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
13 SQL Server 分析和编译时间:
14 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
15
16 SQL Server 执行时间:
17 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
18 SQL Server 分析和编译时间:
19 CPU 时间 = 31 毫秒,占用时间 = 67 毫秒。
20
21 (167 行受影响)
22 表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
23 表 'CT_FuelingData'。扫描计数 1,逻辑读取 31 次,物理读取 1 次,预读 64 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
24 表 'CT_InhouseCard'。扫描计数 1,逻辑读取 2 次,物理读取 1 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
25
26 (4 行受影响)
27
28 SQL Server 执行时间:
29 CPU 时间 = 16 毫秒,占用时间 = 192 毫秒。
EXISTS语句
1 SQL Server 分析和编译时间:
2 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
3
4 SQL Server 执行时间:
5 CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 34 毫秒。
8
9 (167 行受影响)
10 表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
11 表 'CT_FuelingData'。扫描计数 1,逻辑读取 31 次,物理读取 1 次,预读 64 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
12 表 'CT_InhouseCard'。扫描计数 1,逻辑读取 2 次,物理读取 1 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
13
14 (4 行受影响)
15
16 SQL Server 执行时间:
17 CPU 时间 = 0 毫秒,占用时间 = 163 毫秒。
大家可以看到除了执行时间有一点差别,IO是一样的
因为数据量比较大,所以两个查询都用到了Worktable(中间表)来存储中间结果
H. sqlserver中想用in判断范围,但只能输入一个字符串参数,如何拆字符串然后动态拼in()里面的内容呢
字符串应该类似'a,b,c,d' 或者'1,2,3,4'这样的吧?
拼字符串 set @str='select * from tb where 字段 in ('+char(39)+replace('字符串',',',char(39)+','+char(39)))+char(39)+')'
exec(@str)
就是把'a,b,c,d' 替换成 ('a','b','c','d')
I. sqlserver的查询结果按照in条件顺序输出
按指定顺序输出数据,可以使用order bycharindex(','+convert(varchar,ID)+',',',3,1,2,5,4,')的方法来实现这个目的
selectid,title
fromtbname
whereidin(3,1,2,5,4)
orderbycharindex(','+convert(varchar,ID)+',',',3,1,2,5,4,')
J. SqlServer中in和exists的区别效率问题
in和exists
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表梁或进行查询。
如果两个表中一个较小,一个是大表悄渣神,则子查询表大的用exists,子查启亏询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');与
select name from student where name='zhang' or name='li' or
name='wang' or name='zhao'
的结果是相同的。