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语句会使用聚集索引查找,因为包括了创建聚集索引的时候的第一个字段

 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语句会使用非聚集索引查找,因为包括了创建非聚集索引的时候的第一个字段

 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查找:到堆表里找其他字段的值

时间: 2024-10-31 14:03:10

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

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

from http://www.itpub.net/thread-1852897-1-1.html 有论坛朋友在上面的帖子里问SQL为什么不走索引,正好这两天我也刚刚在看SQL优化,于是试着回答了一下. 下面是原来的SQL: select o.order_id as orderId  from order_info o, member mwhere m.member_id = o.member_id   and o.is_delete = 'N'   /*and (to_date(nvl(o.p

在数据库查询中不走索引的情况与压力测试

重点关注: 1) 没有查询条件,或者查询条件没有建立索引 例如: select * from tab; 全表扫描. select * from tab where 1=1; 在业务数据库中,特别是数据量比较大的表.是没有全表扫描这种需求. 1.对用户查看是非常痛苦的. 2.对服务器来讲毁灭性的. 例如: select * from tab; SQL改写成以下语句: selec * from tab order by price limit 10 需要在price列上建立索引 select * f

oracle 不走索引的几种情况

不走索引的其它原因:   1.建立组合索引,但查询谓词并未使用组合索引的第一列,此处有一个INDEX SKIP SCAN概念.   2.在包含有null值的table列上建立索引,当时使用select count(*) from table时不会使用索引.   3.在索引列上使用函数时不会使用索引,如果一定要使用索引只能建立函数索引.   4.当被索引的列进行隐式的类型转换时不会使用索引.如:select * from t where indexed_column = 5,而indexed_co

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

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

Oracle直方图导致SQL不走索引.

在ITPUB 上看到一个帖子 http://www.itpub.net/thread-1875212-1-1.html 同一条SQL语句,只有查询条件不一样,查询返回的结果集都为0,一个走了全表扫描,一个走索引.查看全表扫描的SQL语句:SQL走全表,产生了2422609个逻辑读,cost为535KSQL> SELECT URL,YHZH,HFRZY,HFLR,SPURL,TPURL,YPURL,SCSJ,LY,JCSJ FROM YHXX_HFXX T 2       WHERE T.URL=

mysql索引和正确使用方式

一.索引类型 B树索引:大部分都是,因此B树的特性限制了索引如何使用:必须看看索引的正确使用限制(含组合索引的限制)http://blog.csdn.net/lovemdx/article/details/17683647 hash索引:只有Memory引擎支持 二.B树索引的正确使用 select d from table where A = "x" and B= "y" and C = "z" :此时对A B C均能使用索引 select d

存储过程不走索引的第二次记录

1.故障现象业务连接返回超时,数据库大量线程卡在了updating状态,锁等待十分严重,主机性能反而正常2.初步的处理查看错误日志,发现一个存储过程的执行时间很长,差不多1000s左右,打开存储过程,果然发现里面的某条语句就是卡在updating的语句:初步定位到单条sql导致的数据库卡顿,分析存储过程里面的sql,对比表索引,利用explain获取sql执行计划,竟然是走了索引的.3.环境介绍由于是一个大量的并发业务,存储过程如下 delimiter $$ CREATE PROCEDURE `

oracle 不走索引的原因

create table tb2 as select * from emp;alter table tb2 modify empno number(4) not null;翻到20W行 create index idxtb21 on tb2(empno); select INDEX_NAME from dba_indexes where table_name='TB2';--验证index建立起来 set autotrace on; select distinct empno from tb2;

Oracle不走索引的原因

Oracle数据库操作中,为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?本文我们主要就介绍这部分内容,接下来就让我们一起来了解一下  .        不走索引大体有以下几个原因:        你在Instance级别所用的是all_rows的方式        你的表的统计信息(最可能的原因)        你的表很小,上文提到过的,Oracle的优化器认为不值得走索引  .        解决方法:        可以修改init.ora中的OPTI