zoukankan      html  css  js  c++  java
  • 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
    View Code

    非聚集索引

     
     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
    View Code

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


    一张表有多列的情况

    分三种情况:

    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
    View Code

    小结:

    仅仅有聚集索引的表:假设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
    View Code

    小结:

    仅仅有非聚集索引的表:假设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
    View Code

    小结:

    有聚集索引和非聚集索引的表:假设where后面包含创建聚集索引的时候的第一个字段。就会使用聚集索引查找

    假设where后面包含创建非聚集索引的时候的第一个字段但不包含创建聚集索引的时候的第一个字段。就会使用索引查找

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

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


    总结

    事实上走不走索引,关键取决于where后面包含还是不包含

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

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

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

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

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

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

  • 相关阅读:
    C# 建立快捷方式
    ae中gp执行 Error HRESULT E_FAIL has been returned from a call to a COM component错误
    AE编辑点要素编辑
    噱头还是革命 云计算“泡沫”五年后改变世界? 狼人:
    分析:英特尔收购McAfee的三大意义 狼人:
    云安全:防护“工具”还是攻击“利器” 狼人:
    热点:安全问题是否能将DNS推入云服务 狼人:
    迈克菲收购tenCube 打造新一代移动安全平台 狼人:
    戴尔推免费浏览器安全工具 可隔离恶意软件 狼人:
    黑帽大会:HTTPS和SSL协议存在安全漏洞 狼人:
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6991309.html
Copyright © 2011-2022 走看看