Select * 一定不走索引是否正确?

走索引指的是:SQL语句的执行计划用到了1、聚集索引查找  2、索引查找  ,并且查询语句中需要有where子句

根据where子句的过滤条件,去聚集索引或非聚集索引那里查找记录

一张表只有一列的情况:

聚集索引

USE [tempdb]
GO
CREATE TABLE t1 ( id INT )
GO
CREATE CLUSTERED INDEX CIX_T1 ON [dbo].[t1](ID ASC)
GO DECLARE @I INT
SET @I = 1
WHILE @I < 1000
BEGIN
INSERT INTO [dbo].[t1] ( [id] )
SELECT @I
SET @I = @I + 1
END
SELECT * FROM [dbo].[t1] WHERE [id]=20

非聚集索引

USE [tempdb]
GO
CREATE TABLE t2 ( id INT )
GO
CREATE NONCLUSTERED INDEX IX_T2 ON [dbo].[t2](ID ASC)
GO DECLARE @I INT
SET @I = 1
WHILE @I < 1000
BEGIN
INSERT INTO [dbo].[t2] ( [id] )
SELECT @I
SET @I = @I + 1
END
SELECT * FROM [dbo].[t2] WHERE [id]=20

只有一列,肯定会走索引的


一张表有多列的情况

分三种情况:

1、只有聚集索引

2、只有非聚集索引

3、有聚集索引和非聚集索引


只有聚集索引

--只有聚集索引
USE [tempdb]
GO
CREATE TABLE Department
(
DepartmentID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
Name NVARCHAR(200) NOT NULL ,
GroupName NVARCHAR(200) NOT NULL ,
Company NVARCHAR(300) ,
ModifiedDate DATETIME NOT NULL DEFAULT ( GETDATE() )
) DECLARE @i INT
SET @i=1
WHILE @i < 100000
BEGIN
INSERT INTO Department ( name, [Company], groupname )
VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' )
SET @i = @i + 1
END SELECT * FROM [dbo].[Department] WHERE [DepartmentID]=2

小结:

只有聚集索引的表:如果where后面不包括创建聚集索引的时候的第一个字段,就会使用聚集索引扫描

下面SQL语句会使用聚集索引查找,因为包括了创建聚集索引的时候的第一个字段

1 SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12

只有非聚集索引

--只有非聚集索引
USE [tempdb]
GO

CREATE TABLE Department
(
DepartmentID INT IDENTITY(1, 1) NOT NULL ,
Name NVARCHAR(200) NOT NULL ,
GroupName NVARCHAR(200) NOT NULL ,
Company NVARCHAR(300) ,
ModifiedDate DATETIME NOT NULL DEFAULT ( GETDATE() )

)

CREATE NONCLUSTERED INDEX IX_Department ON Department(DepartmentID ASC)

DECLARE @i INT
SET @i=1
WHILE @i < 100000
BEGIN
INSERT INTO Department ( name, [Company], groupname )
VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' )
SET @i = @i + 1
END

SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12

小结:

只有非聚集索引的表:如果where后面不包括创建非聚集索引的时候的第一个字段,就会使用表扫描或者索引扫描

下面SQL语句会使用非聚集索引查找,因为包括了创建非聚集索引的时候的第一个字段

1 SELECT * FROM [dbo].[Department] WHERE [Company]='销售部12' AND [DepartmentID]=12

有聚集索引也有非聚集索引

--有聚集索引和非聚集索引
USE [tempdb]
GO

CREATE TABLE Department
(
DepartmentID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
Name NVARCHAR(200) NOT NULL ,
GroupName NVARCHAR(200) NOT NULL ,
Company NVARCHAR(300) ,
ModifiedDate DATETIME NOT NULL DEFAULT ( GETDATE() )

)

CREATE NONCLUSTERED INDEX IX_Department ON Department(Company ASC)

DECLARE @i INT
SET @i=1
WHILE @i < 100000
BEGIN
INSERT INTO Department ( name, [Company], groupname )
VALUES ( '销售部'+CAST(@i AS VARCHAR(200)), '中国你好有限公司XX分公司', '销售组' )
SET @i = @i + 1
END

小结:

有聚集索引和非聚集索引的表:如果where后面包括创建聚集索引的时候的第一个字段,就会使用聚集索引查找

如果where后面包括创建非聚集索引的时候的第一个字段但不包括创建聚集索引的时候的第一个字段,就会使用索引查找

如果where后面不包括创建非聚集索引的时候的第一个字段和不包括创建聚集索引的时候的第一个字段,就会使用聚集索引扫描

1 SELECT * FROM [dbo].[Department] WHERE [GroupName]='销售组'


总结

其实走不走索引,关键取决于where后面包括还是不包括

创建聚集索引的时候的第一个字段

创建非聚集索引的时候的第一个字段

跟select *没有关系的,select * 最大的影响就是额外的IO开销

像“键查找” ,“RID查找”这些运算符就是额外的开销

键查找:到聚集索引里找其他字段的值

RID查找:到堆表里找其他字段的值

而在宋大侠的文章里:有关T-SQL的10个好习惯

他说到:

造成额外的书签查找或是由查找变为扫描

由查找变为扫描,查找还是扫描决定于我刚才所说的话:

其实走不走索引,关键取决于where后面包括还是不包括

创建聚集索引的时候的第一个字段

创建非聚集索引的时候的第一个字段

如果大家不是很明白,可以看一下我所写的文章,我在文章里对聚集索引跟非聚集索引的研究还是比较透彻的

SQLSERVER聚集索引与非聚集索引的再次研究(上)

SQLSERVER聚集索引与非聚集索引的再次研究(下)

当然,您也不能把整个表的字段全部放到索引里,以消除额外IO开销,要针对实际情况,

该把要加入索引的字段就加入索引,不该把不用加入索引的字段不要加入索引

那么您刚才说:走索引不是where后面包括还是不包括创建索引的第一个字段吗???既然这样创建索引的时候只包括一个字段就好了

大家可以看一下SQLSERVER聚集索引与非聚集索引的再次研究(下),其实非聚集索引扫描也是很有用的

而聚集索引就只包括一个字段就行了,非聚集索引可以包括多个字段,详细还是看一下下面两篇文章吧o(∩_∩)o

SQLSERVER聚集索引与非聚集索引的再次研究(上)

SQLSERVER聚集索引与非聚集索引的再次研究(下)

不过大家还是不要用select * 比较好,老老实实写上字段名

有一些偷懒的人总是会有他的理由:

如果表结构改变我就不用修改代码 ,方便省事,一个select *搞定,项目这麽紧张还写上字段干嘛???

如果您是上面那种人,那好吧,当我没说过好了o(∩_∩)o

如有不对的地方,欢迎大家拍砖哦o(∩_∩)o

 

Select * 一定不走索引是否正确?的更多相关文章

  1. 诊断一句SQL不走索引的原因

    from http://www.itpub.net/thread-1852897-1-1.html 有论坛朋友在上面的帖子里问SQL为什么不走索引,正好这两天我也刚刚在看SQL优化,于是试着回答了一下 ...

  2. oracle查询不走索引的一些情况(索引失效)

    Oracle建立索引的目的是为了避免全表扫描,提高查询的效率. 但是有些情况下发现即使建立了索引,但是写出来的查询还是很慢,然后会发现是索引失效导致的,所以需要了解一下那些情况会导致索引失效,即查询不 ...

  3. mysql 索引优化,索引建立原则和不走索引的原因

    第一:选择唯一性索引 唯一性索引的值是唯一的,可以更快捷的通过该索引来确定某条记录. 2.索引的列为where 后面经常作为条件的字段建立索引 如果某个字段经常作为查询条件,而且又有较少的重复列或者是 ...

  4. Mysql-高性能索引策略及不走索引的例子总结

    Mysql-高性能索引策略 正确的创建和使用索引是实现高性能查询的基础.我总结了以下几点索引选择的策略和索引的注意事项: 索引的使用策略: (PS:索引的选择性是指:不重复的索引值,和数据表的记录总数 ...

  5. SQL语句优化、mysql不走索引的原因、数据库索引的设计原则

    SQL语句优化 1 企业SQL优化思路 1.把一个大的不使用索引的SQL语句按照功能进行拆分 2.长的SQL语句无法使用索引,能不能变成2条短的SQL语句让它分别使用上索引. 3.对SQL语句功能的拆 ...

  6. Update关联查询不走索引,效率低下

    优化一个sql,就是有A,B两个表,要利用b表的字段更新a表对应的字段.形如 Sql代码 update A set A.a=(select B.b from B where A.id=B.id); 原 ...

  7. 【摘】Oracle执行计划不走索引的原因总结

    感谢原博主 http://soft.chinabyte.com/database/364/12471864.shtml 在Oracle数据库操作中,为什么有时一个表的某个字段明明有索引,当观察一些语的 ...

  8. MySql Delete不走索引问题

    如果delete语句带有查询,写法不对会导致不走索引. 简单粗暴的办法:拆两条sql,一条查询,一条delete ======================= [不走索引的写法] DELETE FR ...

  9. oracle 不走索引的原因

    create table tb2 as select * from emp;alter table tb2 modify empno number(4) not null;翻到20W行 create ...

随机推荐

  1. HDFS副本放置策略和机架感知

    副本放置策略 的副本放置策略的基本思想是: 第一block在复制和client哪里node于(假设client它不是群集的范围内,则这第一个node是随机选取的.当然系统会尝试不选择哪些太满或者太忙的 ...

  2. Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试

    Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试   需要FQ才能安装,使用时应该不用FQ了,除非使用postman的历史记录功能:   非常棒的C ...

  3. 【百度地图API】如何用圆形搜索获取中心点周围100米内全部关键点?如天安门附近所有的餐厅、加油站、宾馆、大厦等

    原文:[百度地图API]如何用圆形搜索获取中心点周围100米内全部关键点?如天安门附近所有的餐厅.加油站.宾馆.大厦等 摘要: 在LBS上有这样一个常用的功能,查找附近所有的关键点(POI点,比如标志 ...

  4. 欧拉计划&#183;Q8

    题目8:找出这个1000位数字中连续13个数字乘积的最大值. 找出下面这个1000位的整数中连续13个数字的最大乘积. 7316717653133062491922511967442657474235 ...

  5. 详细的图文介绍如何利用XAMPP本地建站的环境配置教程

    原文:详细的图文介绍如何利用XAMPP本地建站的环境配置教程 WordPress 是一个简便快捷,用途广,人气旺的一个开源的博客建站程序.很有很多等您去发现. 简便快捷:在性能上易于操作.易于浏览: ...

  6. asp.net webForm 前后台类关系

    要研究这个,首先要新建网站, protected void Page_Load(object sender, EventArgs e) { string str = System.Reflection ...

  7. 收集整理的非常有用的PHP函数

    原文:收集整理的非常有用的PHP函数 项目中经常会需要一些让人头疼的函数,作为开发者应该整理一个自己的函数库,在需要之时复制过来即可.本文作者收集整理数十个PHP项目中常用的函数,保证能正常运行,你只 ...

  8. 快速构建Windows 8风格应用34-构建Toast通知

    原文:快速构建Windows 8风格应用34-构建Toast通知 引言 开发过WindowsPhone应用或者使用过WindowsPhone手机的开发者都知道,我们会收到一些应用的提示信息,这些提示信 ...

  9. 设置Cookie,登录记住用户登录信息,获取用户登录过得信息

    function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Da ...

  10. 使用javaservice 将jboss 注册为服务

    近来做项目,需要jboss定期重新启动.不想再看到jboss启动那个黑洞洞的窗口,就想着把它注册为服务,然后在net start.恰好objectweb上有个open source的javaservi ...