1. 程式人生 > >SQL Server 索引和表體系結構(包含列索引)

SQL Server 索引和表體系結構(包含列索引)

包含列索引

概述

包含列索引也是非聚集索引,索引結構跟聚集索引結構是一樣,有一點不同的地方就是包含列索引的非鍵列只儲存在葉子節點;包含列索引的列分為鍵列和非鍵列,所謂的非鍵列就是INCLUDE中包含的列,至少需要有一個鍵列,且鍵列和非鍵列不允許重複,非鍵列最多允許1023列(也就是表的最多列-1),由於索引鍵列(不包括非鍵)必須遵守現有索引大小的限制(最大鍵列數為 16,總索引鍵大小為 900 位元組)的要求所以引進了包含列索引。

正文

  • 建立包含列索引
----建立表
CREATE TABLE [dbo].[Customers](
    [custid] [int] IDENTITY
(1,1) NOT NULL, [companyname] [nvarchar](40) NOT NULL, [contactname] [nvarchar](30) NOT NULL, [contacttitle] [nvarchar](400) NOT NULL, CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED ( [custid] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS =
ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] ----建立包含列索引 CREATE NONCLUSTERED INDEX [IX1_Customers] ON [dbo].[Customers] ( [companyname] ASC ) INCLUDE ( [contactname])
WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO

這裡的鍵列就是:
companyname
非鍵列就是:contactname

非鍵列具有下列優點:

    • 它們可以是不允許作為索引鍵列的資料型別。

    • 在計算索引鍵列數或索引鍵大小時,資料庫引擎不考慮它們。

當查詢中的所有列都作為鍵列或非鍵列包含在索引中時,帶有包含性非鍵列的索引可以顯著提高查詢效能。這樣可以實現效能提升,因為查詢優化器可以在索引中找到所有列值;不訪問表或聚集索引資料,從而減少磁碟 I/O 操作。(當索引包含查詢引用的所有列時,它通常稱為“覆蓋查詢”。)

  • 建立覆蓋查詢

 覆蓋查詢就是建立的索引列包含查詢所引用的所有列時

  1. 查詢列都設為鍵列
當我們的SELECT查詢是這樣的
SELECT 
       [companyname]
      ,[contactname]
      ,[contacttitle]
  FROM [chenmh].[dbo].[Customers]
  where companyname='好孩子'
  
  
---這時我們選擇將索引列都包含在索引建列中  
CREATE NONCLUSTERED INDEX [IX2_Customers] ON [dbo].[Customers] 
(
      
       [companyname] ASC
      ,[contactname] ASC
      ,[contacttitle] ASC
)
WITH (STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

將會彈出警告:警告! 最大鍵長度為 900 個位元組。索引 'IX2_Customers' 的最大長度為 940 個位元組。對於某些大值組合,插入/更新操作將失敗。
由於三個欄位都是NVARCHAR欄位型別,每個字元需要 2 個位元組,(40+30+400)*2=940個位元組,大於900位元組,這時我們可以將
[contactname] ,[contacttitle]包含在非鍵列中

2.將大資料型別設為非鍵列

CREATE NONCLUSTERED INDEX [IX3_Customers] ON [dbo].[Customers] 
(
      
       [companyname] ASC
      
)
INCLUDE ( [contactname]
        ,[contacttitle])
WITH (STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

這時索引鍵大小所佔字元就只有40*2=80個位元組,同時索引也是覆蓋索引,索引的列包含查詢用到的列,當我們查詢資料時直接在索引頁中查詢資料就可以,不需要訪問資料頁,減少磁碟IO,提高效能

帶有包含列的索引準則

設計帶有包含列的非聚集索引時,請考慮下列準則:

    • 在 CREATE INDEX 語句的 INCLUDE 子句中定義非鍵列。
    • 只能對錶或索引檢視的非聚集索引定義非鍵列。
    • textntextimage 之外,允許所有資料型別。
    • 精確或不精確的確定性計算列都可以是包含列。有關詳細資訊,請參閱為計算列建立索引。
    • 與鍵列一樣,只要允許將計算列資料型別作為非鍵索引列,從 imagentexttext 資料型別派生的計算列就可以作為非鍵(包含性)列。
    • 不能同時在 INCLUDE 列表和鍵列列表中指定列名。
    • INCLUDE 列表中的列名不能重複。

列大小準則

    • 必須至少定義一個鍵列。最大非鍵列數為 1023 列。也就是最大的表列數減 1。
    • 索引鍵列(不包括非鍵)必須遵守現有索引大小的限制(最大鍵列數為 16,總索引鍵大小為 900 位元組)。
    • 所有非鍵列的總大小隻受 INCLUDE 子句中所指定列的大小限制;例如,varchar(max) 列限制為 2 GB。

列修改準則

修改已定義為包含列的表列時,要受下列限制:

    • 除非先刪除索引,否則無法從表中刪除非鍵列。
    • 除進行下列更改外,不能對非鍵列進行其他更改:

      • 將列的為空性從 NOT NULL 改為 NULL。
      • 增加 varcharnvarcharvarbinary 列的長度。

注意事項

  • 鍵列的大小盡量小,有利用提高效率
  • 將用於搜尋和查詢的列為鍵列,鍵列儘量不要包含沒必要的列。(例如上面建立的覆蓋查詢列,雖然companyname+contactname加起來作為鍵列也不會超過900位元組,但是這樣鍵大小就變大了,降低了查詢效率)
  • 避免新增不必要的列。新增過多的索引列(鍵列或非鍵列)會對效能產生下列影響:
    • 一頁上能容納的索引行將更少。這樣會使 I/O 增加並降低快取效率。
    • 需要更多的磁碟空間來儲存索引。特別是,將 varchar(max)nvarchar(max)varbinary(max)xml 資料型別新增為非鍵索引列會顯著增加磁碟空間要求。這是因為列值被複制到了索引葉級別。因此,它們既駐留在索引中,也駐留在基表中。
    • 索引維護可能會增加對基礎表或索引檢視執行修改、插入、更新或刪除操作所需的時間

備註:

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明連結,否則保留追究責任的權利。

《歡迎交流討論》

相關推薦

SQL Server 索引體系結構包含索引

包含列索引 概述 包含列索引也是非聚集索引,索引結構跟聚集索引結構是一樣,有一點不同的地方就是包含列索引的非鍵列只儲存在葉子節點;包含列索引的列分為鍵列和非鍵列,所謂的非鍵列就是INCLUDE中包含的列,至少需要有一個鍵列,且鍵列和非鍵列不允許重複,非鍵列最多允許1023列(也就是表的最多列-1),由於索

SQL Server 索引體系結構非聚集索引

非聚集索引 概述      對於非聚集索引,涉及的資訊要比聚集索引更多一些,由於整個篇幅比較大涉及接下來的要寫的“包含列的索引”,“索引碎片”等一些知識點,可能要結合起來閱讀理解起來要更容易一些。非聚集索引和聚集索引一樣都是B-樹結構,但是非聚集索引不改變資料的儲存方式,所以一個表允許建多個非聚集索引;非

SQL Server 索引體系結構聚集索引

聚集索引 概述       關於索引和表體系結構的概念一直都是討論比較多的話題,其中表的各種儲存形式是討論的重點,在各個網站上面也有很多關於這方面寫的不錯的文章,我寫這篇文章的目的也是為了將所有的知識點儘可能的組織起來結合自己對這方面的瞭解些一篇關於的詳細文章出來,同時也會列出一些我自己有疑惑的地方拿出來

ES6 SetMap資料結構可轉為陣列

一:Set 基本用法 ES6 提供了新的資料結構 Set。它類似於陣列,但是成員的值都是唯一的,沒有重複的值。(不包括空物件) Set 本身是一個建構函式,用來生成 Set 資料結構。 const s = new Set(); [2, 3, 5, 4, 5, 2, 2].forE

SQL Server調優系列基礎篇並行運算總結

前言 上三篇文章我們介紹了檢視查詢計劃的方式,以及一些常用的連線運算子、聯合運算子的優化技巧。 本篇我們分析SQL Server的並行運算,作為多核計算機盛行的今天,SQL Server也會適時調整自己的查詢計劃,來適應硬體資源的擴充套件,充分利用硬體資源,最大限度的提高效能。 閒言少敘,直接進入本篇的

SQL Server調優系列基礎篇聯合運算子總結

前言 上兩篇文章我們介紹了檢視查詢計劃的方式,以及一些常用的連線運算子的優化技巧,本篇我們總結聯合運算子的使用方式和優化技巧。 廢話少說,直接進入本篇的主題。 技術準備 基於SQL Server2008R2版本,利用微軟的一個更簡潔的案例庫(Northwind)進行解析。 一、聯合運算子 所謂的聯

SQL Server 2014新特性——基數評估白皮書閱讀筆記

基數評估 目錄 說明 查詢優化器的目的是為了找出有效的執行計劃,根據cost運算,取出cost最小的計劃,作為執行計劃。其中影響cost最重要的一項就是基數評估(估計行數)。SQL Server 2014

Windows10安裝SQL server 2016/2014 失敗解決方法 錯誤程式碼: 0x851A0019

最近想學資料庫,但是在安裝SQL2014時總是失敗,原因是  ( 錯誤程式碼: 0x851A0019)找不到資料庫引擎啟動控制代碼!網上找了很多解決方法都無效。我以為是應為Win10系統的原因,就裝了SQL2016但是依然因同樣的原因而失敗,直到我看到這個部落格:http

使用者sa登入失敗,該使用者與可信SQL server連線無關聯 錯誤18452遠端資料庫訪問

//******************************************************** 在這裡插一點:SQL server 安裝時(不論是2000還是2005)需要選擇使用本地連線和混合模式。在SQL server 2000安裝時,例項名最好選

SQL Server 大資料管理——資料歸檔主檔案備份

SQL Server 大資料管理——資料歸檔背景:        資料庫幾百GB,甚至TB級別資料庫,歷史資料偶爾會用到,不能直接刪除,就需要定期歸檔歷史資料。以往在歸檔歷史資料方案:方案1:做全備儲存歸檔資料,刪除線上庫歸檔資料方案2:建立一個新庫,將歸檔資料匯入到新庫,備

SQL Server 向資料庫中新增主鍵

        SQL Server 資料庫,向已設定主鍵的資料庫表中插入新一列,並設為主鍵。         首先從基礎知識開始看,         建表: create table 表名

SQL Server儲存過程,傳送陣列引數多個引數的變通辦法

        最近在做開發過程中碰到這麼一個糾結的問題,需要同時插入N條資料,不想在程式裡控制,但是SQL Sever又不支援陣列引數.所以只能用變通的辦法了.利用SQL Server強大的字串處理傳把陣列格式化為類似"3500320083208#350060052089

SQL Server復制結構數據生成新的語句

sdn 主鍵 .net 需要 topic 外鍵 server sql 表數據 參考:http://topic.csdn.net/t/20020621/09/820025.html SELECT * INTO newTableName FROM oldT

Oraclesql server中複製結構資料的sql語句

 在Oracle和sql server中,如何從一個已知的舊錶,來複制新生成一個新的表,如果要複製舊錶結構和表資料,對應的sql語句該如何寫呢?剛好阿堂這兩天用到了,就順便把它收集彙總一下,供朋友們參考一下了! sql server中複製表結構和表資料的sql語句的寫法,分別如下1.複製表的內容到

利用DBCC PAGE檢視SQL Server中的索引資料

1.DBCC IND跟DBCC PAGE簡介 1.1.DBCC IND命令 DBCC IND ( { 'dbname' | dbid }, { 'objname' | objid }, { nonclustered indid | 1 | 0 | -1 | -

SQL Server 建立使用索引 轉載

使用CREATE INDEX語句建立索引: CREATE[ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX索引名 ON {表名|檢視名} (列名[ ASC | DESC ] [ ,...n ] ) 例: 在資料庫HrSystem中為表Employees建立基於IDC

Sql Server無法修改結構

修改完表結構點儲存之後彈出錯誤提示:不允許儲存更改。您所做的更改要求刪除並重新建立以下表。您對無法重新建立的表進行了更改或者啟用了‘阻止儲存要求重新建立表的更改’選項   解決辦法:開啟sql server management studio--

sql server 查詢所有結構

SELECT CASE WHEN col.colorder = 1 THEN obj.name ELSE '' END AS 表名, Coalesce(epTwo.value, '') AS documentation, col.colorder AS 序號 , col.name AS 列名 , ISNULL

用C語言實現線性歸併_含原始碼執行結果_資料結構C語言版

採用動態分配順序儲存結構實現 採用單鏈表結構實現 1.採用動態分配實現 #include<stdio.h> #include<stdlib.h> #define LIST_INIT_SIZE 100 #define LISTINCREM

SQL Server調優系列基礎篇索引運算總結

前言 上幾篇文章我們介紹瞭如何檢視查詢計劃、常用運算子的介紹、並行運算的方式,有興趣的可以點選檢視。 本篇將分析在SQL Server中,如何利用先有索引項進行查詢效能優化,通過了解這些索引項的應用方式可以指導我們如何建立索引、調整我們的查詢語句,達到效能優化的目的。 閒言少敘,進入本篇的正題。 技術