在5月1号,我写了一篇《软件系统性能优化策略--SQL优化》的博文,该文章的主题我主要是想说明在SQL优化中,首先要考虑索引优化,往往在建立索引之后会给你带来意想不到的效果。但是我在写结论的时候,这样写道:
1、在索引字段中使用OR或者IN
例:Select * from table1 where id in (2,3) 或者 Select * from table1 where id=2 or tid=3
这些写法都会让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 ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE 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 int
set @i=1
while @i |