写技术类博文,我们需要更严谨的精神--【非常抱歉我扯蛋了】
在索引字段中使用OR或者IN例Select * from table1 where id in (2,3) 或者 Select * from table1 where id2 or tid3这些写法都会让id索引失效而引起全表历遍当然当数据没有达到海量的时候你爱这么写都可以只要实现功能一旦达到海量便一个细节决定成败解决方案一Select * from table1 where id 2 UNION Select * from table1 where id 3当然大家也可以用别的写法来实现功能。其实我在写条结论的时候自己并没有去测试因为在之前我看过很多网上的这个方面的技术博文在IN和OR的阐述中他们都在结论中写道会影响到索引。当时我也依样画葫芦写了这句话。后来在博文发表之后一位名叫 喳喳鸟 朋友这样评论我很明确的告诉你这是扯淡id in(2,3) 以及 or 的写法都能很好的利用索引而不会导致全表扫描。看到这里后面的我就不想看了以免被误导。当时我看到这样的评论心情很不爽五一长假放弃休息写篇博文和大家分享却得来这样的评论但是后来想想对于这样的结论我是没有测试过如果因为我这样的误论而误导大家我觉得要比我的心情更重要。当时我就发了邮件给微软数据库方面专家希望能得到他们的更权威的结论可惜他们没有理我这个小菜鸟。那只能靠自己了。第一步首先创建一张100W数据的表代码USE [MYDBTest]GO/****** 对象: Table [dbo].[DepositTran] 脚本日期: 05/06/2010 21:15:34 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[DepositTran]([ID] [int] IDENTITY(1,1) NOT NULL,[Name] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,[Deposit] [float] NOT NULL,[UpdateTime] [datetime] NOT NULL,CONSTRAINT [PK_Transaction] PRIMARY KEY CLUSTERED([ID] ASC)WITH (IGNORE_DUP_KEY OFF) ON [PRIMARY]) ON [PRIMARY]declare i intset i1while i100000begininsert into DepositTran(Name,Deposit,UpdateTime) values(周菲菲,500,2009-08-08)set ii1endGOdeclare i intset i1while i100000begininsert into DepositTran(Name,Deposit,UpdateTime) values(费佳杰,1100,2009-09-18)set ii1endGOdeclare i intset i1while i100000begininsert into DepositTran(Name,Deposit,UpdateTime) values(周建飞,1500,2009-09-28)set ii1endGOdeclare i intset i1while i300000begininsert into DepositTran(Name,Deposit,UpdateTime) values(金刚波,2500,2009-12-08)set ii1endGOdeclare i intset i1while i400000begininsert into DepositTran(Name,Deposit,UpdateTime) values(马腾,3500,2010-02-08)set ii1endGODepositTran[存款交易表]在该表中ID主键是聚集索引NAME是非聚集索引Deposit 表示存款金额UpdateTime 是交易时间运行上面的脚本 我们就有了张百万数据的表了这时候我们来介绍我们这次进行这次任务的SQL命名set statistics io onset statistics time on首先我们运行如下脚本首先我们来测试 where 条件 为“”测试字段为ID聚集索引dbcc dropcleanbuffersdbcc freeproccacheset statistics io onset statistics time onSelect ID,Name,Deposit,UpdateTime from DepositTran where id 2在消息框中显示(1 行受影响)表 DepositTran。扫描计数 0逻辑读取 3 次物理读取 3 次预读 0 次lob 逻辑读取 0 次lob 物理读取 0 次lob 预读 0 次。SQL Server 执行时间:CPU 时间 0 毫秒占用时间 57 毫秒。然后我们来测试INdbcc dropcleanbuffersdbcc freeproccacheset statistics io onset statistics time onSelect ID,Name,Deposit,UpdateTime from DepositTran where id in(2)