sql組合索引
⑴ 試列舉何種情況考慮創建索引,在sql中
轉:
---使用索引優化資料庫查詢效率
1.不宜創建索引的情形
(1)經常插入,修改和刪除的表
(2)數據量比較小的表,因為查詢優化器在搜索索引時所花費的時間可能會大於遍歷全表的數據所需要的時間
2.適合創建索引的情形
(1)為where子句中出現的列創建索引
(2)創建組合索引
(3)為group by 子句中出現的列創建索引
3.聚集索引的設計原則
(1)該列的數值是唯一的或者很少有重復的記錄
(2)經常使用between ...and..按順序查詢的列
(3)定義identity的唯一列.
(4)經常用於對數據進行排序的列.
---無法使用索引的select語句
1.對索引列使用了函數,如:
select * from tb where max(id)=100
2.對索引列使用了'%xx',如:
select * from tb where id like '%1'
需要注意的不是所有使用like關鍵字的select 語句都無法使用索引,比如
select * from tb where id like '1%'就可以使用索引
3.在where子句中對列進行類型轉換(其實也是使用到了函數)
4.在組合索引的第1列不是使用最多的列,如在下面3個查詢語句中建立組合索引,按順序包含col2,col1,id列;
select * from tb where id='1' and col1='aa'
select id,sum(col1) from tb group by id
select * from tb where id='2' and col2='bb'
則第一句和第二句無法使用到索引 所以需要注意組合索引的順序
5.在where 子句中使用in關鍵字的某些句子
當在in關鍵字後面使用嵌套的select語句,將無法使用在該列上定義的索引
如:
select
*
from
ta
where
id
in
(select id from tb where ....)
--這樣可以用到索引
select * from tb where id in('1','2')
⑵ mysql有幾種索引類型使用索引時都有那些地方要注意sql優化原則是什麼
mysql的索引類型及使用索引時的注意事項有:
一、普通索引。這是最基本的索引,它沒有任何限制。它有以下幾種創建方式:
1、創建索引
代碼如下:
CREATE INDEX indexName ON mytable(username(length));
如果是CHAR,VARCHAR類型,length可以小於欄位實際長度;如果是BLOB和TEXT類型,必須指定 length,下同。
2、修改表結構
代碼如下:
ALTER mytable ADD INDEX [indexName] ON (username(length)) -- 創建表的時候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) );
-- 刪除索引的語法:
DROP INDEX [indexName] ON mytable;
二、唯一索引。它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創建方式:
代碼如下:
CREATE UNIQUE INDEX indexName ON mytable(username(length))
-- 修改表結構
ALTER mytable ADD UNIQUE [indexName] ON (username(length))
-- 創建表的時候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) );
三、主鍵索引。它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時創建主鍵索引:
代碼如下:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) );
當然也可以用 ALTER 命令。記住:一個表只能有一個主鍵。
四、組合索引。為了形象地對比單列索引和組合索引,為表添加多個欄位:
代碼如下:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL );
為了進一步榨取MySQL的效率,就要考慮建立組合索引。就是將 name, city, age建到一個索引里:
代碼如下:
ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);[code]
建表時,usernname長度為 16,這里用 10。這是因為一般情況下名字的長度不會超過10,這樣會加速索引查詢速度,還會減少索引文件的大小,提高INSERT的更新速度。
如果分別在 usernname,city,age上建立單列索引,讓該表有3個單列索引,查詢時和上述的組合索引效率也會大不一樣,遠遠低於我們的組合索引。雖然此時有了三個索引,但MySQL只能用到其中的那個它認為似乎是最有效率的單列索引。
建立這樣的組合索引,其實是相當於分別建立了下面三組組合索引:usernname,city,age usernname,city usernname 為什麼沒有 city,age這樣的組合索引呢?這是因為MySQL組合索引「最左前綴」的結果。簡單的理解就是只從最左面的開始組合。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個SQL就會用到這個組合索引:
[code]
SELECT * FROM mytable WHREE username="admin" AND city="鄭州" SELECT * FROM mytable WHREE username="admin"
⑶ Sql查詢索引 (應該用組合索引)求教大神指教
索引一般分為聚集索引和非聚集索引,表的主鍵一般都是聚集索引,是自動創建的,而其他欄位可以創建成為非聚集索引,索引相當於書本的目錄,用於快速檢索。創建方法如下:
CREATE NONCLUSTERED 索引名稱 ON 表名(欄位)
你上面的就是CREATE NONCLUSTERED INDEX_Staff_TypeId on Staff (TypeId)
CREATE NONCLUSTERED INDEX_Staff_mondId on Staff (mondId)
索引是你在查詢的時候進行快速檢索,是自動實現的,所以怎麼使用就不用說了吧
⑷ sql server 2008單獨索引與組合索引區別
首先要說明,不是所有的表都適合創建索引,因為索引需要佔用一部分系統資源。
當你使用這個表的時候,如果該表的某個欄位經常用來作為where條件判斷,或者在做join聯查的時候,該欄位建議增加索引。
如果兩個欄位要一起參與where、join條件判斷,建議創建組合索引。
⑸ sql索引分為幾類
SQL SERVER中索引類型包括的三種類型分別是
唯一索引(UNIQUE),聚集索引(CLUSTERED) ,非聚集索引(NONCLUSTERED)。
主鍵與唯一索引的區別
主鍵是一種約束,唯一索引是一種索引,兩者在本質上是不同的。 主鍵創建後一定包含一個唯一性索引,唯一性索引並不一定就是主鍵。 唯一性索引列允許空值,而主鍵列不允許為空值。 主鍵列在創建時,已經默認為空值 + 唯一索引了。
主鍵可以被其他表引用為外鍵,而唯一索引不能。 一個表最多隻能創建一個主鍵,但可以創建多個唯一索引。 主鍵更適合那些不容易更改的唯一標識,如自動遞增列、身份證號等。 在 RBO 模式下,主鍵的執行計劃優先順序要高於唯一索引。 兩者可以提高查詢的速度。
⑹ SQL中一個表可以有幾個聚集索引或非聚集索引
一個表只能有一個聚集索引,可以有多個非聚集索引
下面是聚集索引和非聚集索引的詳細介紹:
聚集索引基於數據行的鍵值在表內排序和存儲這些數據行。每個表只能有一個聚集索引,因為數據行本身只能按一個順序存儲。有關聚集索引體系結構的詳細信息,請參閱聚集索引結構。
每個表幾乎都對列定義聚集索引來實現下列功能:
可用於經常使用的查詢。
提供高度唯一性。
注意:
創建 PRIMARY KEY 約束時,將在列上自動創建唯一索引。默認情況下,此索引是聚集索引,但是在創建約束時,可以指定創建非聚集索引。
可用於范圍查詢。
如果未使用 UNIQUE 屬性創建聚集索引,資料庫引擎將向表自動添加一個 4 位元組的 uniqueifier
列。必要時,資料庫引擎將向行自動添加一個 uniqueifier 值以使每個鍵唯一。此列和列值供內部使用,用戶不能查看或訪問。
查詢注意事項
在創建聚集索引之前,應先了解數據是如何被訪問的。考慮對具有以下特點的查詢使用聚集索引:
使用運算符(如 BETWEEN、>、>=、< 和
<=)返回一系列值。
使用聚集索引找到包含第一個值的行後,便可以確保包含後續索引值的行物理相鄰。例如,如果某個查詢在一系列銷售訂單號間檢索記錄,SalesOrderNumber
列的聚集索引可快速定位包含起始銷售訂單號的行,然後檢索表中所有連續的行,直到檢索到最後的銷售訂單號。
返回大型結果集。
使用 JOIN 子句;一般情況下,使用該子句的是外鍵列。
使用 ORDER BY 或 GROUP BY 子句。
在 ORDER BY 或 GROUP BY
子句中指定的列的索引,可以使資料庫引擎不必對數據進行排序,因為這些行已經排序。這樣可以提高查詢性能。
列注意事項
一般情況下,定義聚集索引鍵時使用的列越少越好。考慮具有下列一個或多個屬性的列:
唯一或包含許多不重復的值
例如,雇員 ID 唯一地標識雇員。EmployeeID 列的聚集索引或 PRIMARY KEY
約束將改善基於雇員 ID 號搜索雇員信息的查詢的性能。另外,可對
LastName、FirstName、MiddleName
列創建聚集索引,因為經常以這種方式分組和查詢雇員記錄,而且這些列的組合還可提供高區分度。
按順序被訪問
例如,產品 ID 唯一地標識 AdventureWorks2008R2 資料庫的
Proction.Proct 表中的產品。在其中指定順序搜索的查詢(如 WHERE ProctID BETWEEN 980
and 999)將從 ProctID 的聚集索引受益。這是因為行將按該鍵列的排序順序存儲。
由於保證了列在表中是唯一的,所以定義為 IDENTITY。
經常用於對表中檢索到的數據進行排序。
按該列對表進行聚集(即物理排序)是一個好方法,它可以在每次查詢該列時節省排序操作的成本。
聚集索引不適用於具有下列屬性的列:
頻繁更改的列
這將導致整行移動,因為資料庫引擎必須按物理順序保留行中的數據值。這一點要特別注意,因為在大容量事務處理系統中數據通常是可變的。
寬鍵
寬鍵是若干列或若干大型列的組合。所有非聚集索引將聚集索引中的鍵值用作查找鍵。為同一表定義的任何非聚集索引都將增大許多,這是因為非聚集索引項包含聚集鍵,同時也包含為此非聚集索引定義的鍵列。
索引選項
創建聚集索引時,可指定若干索引選項。因為聚集索引通常都很大,所以應特別注意下列選項:
SORT_IN_TEMPDB
DROP_EXISTING
FILLFACTOR
ONLINE
非聚集索引包含索引鍵值和指向表數據存儲位置的行定位器。有關非聚集索引體系結構的詳細信息,請參閱非聚集索引結構。
可以對表或索引視圖創建多個非聚集索引。通常,設計非聚集索引是為改善經常使用的、沒有建立聚集索引的查詢的性能。
與使用書中索引的方式相似,查詢優化器在搜索數據值時,先搜索非聚集索引以找到數據值在表中的位置,然後直接從該位置檢索數據。這使非聚集索引成為完全匹配查詢的最佳選擇,因為索引包含說明查詢所搜索的數據值在表中的精確位置的項。例如,為了從
Person.Person 表中查詢具有特定姓氏的人員,查詢優化器可能使用非聚集索引
IX_Person_LastName_FirstName_MiddleName;它以 LastName 作為自己的一個鍵列。查詢優化器能快速找出索引中與指定
LastName
匹配的所有項。每個索引項都指向表或聚集索引中准確的頁和行,其中可以找到相應的數據。在查詢優化器在索引中找到所有項之後,它可以直接轉到准確的頁和行進行數據檢索。
資料庫注意事項
設計非聚集索引時需要注意資料庫的特徵。
更新要求較低但包含大量數據的資料庫或表可以從許多非聚集索引中獲益從而改善查詢性能。與全表非聚集索引相比,考慮為定義完善的數據子集創建篩選索引可以提高查詢性能、降低索引存儲開銷並減少索引維護開銷。
決策支持系統應用程序和主要包含只讀數據的資料庫可以從許多非聚集索引中獲益。查詢優化器具有更多可供選擇的索引用來確定最快的訪問方法,並且資料庫的低更新特徵意味著索引維護不會降低性能。
聯機事務處理應用程序和包含大量更新表的資料庫應避免使用過多的索引。此外,索引應該是窄的,即列越少越好。
一個表如果建有大量索引會影響
INSERT、UPDATE、DELETE 和 MERGE
語句的性能,因為當表中的數據更改時,所有索引都須進行適當的調整。
查詢注意事項
在創建非聚集索引之前,應先了解訪問數據的方式。考慮對具有以下屬性的查詢使用非聚集索引:
使用 JOIN 或 GROUP BY
子句。
應為聯接和分組操作中所涉及的列創建多個非聚集索引,為任何外鍵列創建一個聚集索引。
不返回大型結果集的查詢。
創建篩選索引以覆蓋從大型表中返回定義完善的行子集的查詢。
包含經常包含在查詢的搜索條件(例如返回完全匹配的 WHERE 子句)中的列。
列注意事項
考慮具有以下一個或多個屬性的列:
覆蓋查詢。
當索引包含查詢中的所有列時,性能可以提升。查詢優化器可以找到索引內的所有列值;不會訪問表或聚集索引數據,這樣就減少了磁碟
I/O 操作。使用具有包含列的索引來添加覆蓋列,而不是創建寬索引鍵。有關詳細信息,請參閱
具有包含列的索引
。
如果表有聚集索引,則該聚集索引中定義的列將自動追加到表上每個非聚集索引的末端。這可以生成覆蓋查詢,而不用在非聚集索引定義中指定聚集索引列。例如,如果一個表在
C 列上有聚集索引,則 B 和 A 列的非聚集索引將具有其自己的鍵值列 B、A 和 C。
大量非重復值,如姓氏和名字的組合(前提是聚集索引被用於其他列)。
如果只有很少的非重復值,例如僅有 1 和
0,則大多數查詢將不使用索引,因為此時表掃描通常更有效。對於這種類型的數據,應考慮對僅出現在少數行中的非重復值創建篩選索引。例如,如果大部分值都是
0,則查詢優化器可以對包含 1 的數據行使用篩選查詢。
索引選項
在創建非聚集索引時,可以指定若干索引選項。要尤其注意以下選項:
FILLFACTOR
ONLINE
⑺ sql 索引用多了會越來越卡嗎
1. 執行計劃中明明有使用到索引,為什麼執行還是這么慢?
2. 執行計劃中顯示掃描行數為 644,為什麼 slow log 中顯示 100 多萬行?
a. 我們先看執行計劃,選擇的索引 「INDX_BIOM_ELOCK_TASK3(TASK_ID)」。結合 sql 來看,因為有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能會更差,優化器選擇這個索引避免了排序。
那為什麼不選 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很簡單,TASK_DATE 欄位區分度太低了,走這個索引需要掃描的行數很大,而且還要進行額外的排序,優化器綜合判斷代價更大,所以就不選這個索引了。不過如果我們強制選擇這個索引(用 force index 語法),會看到 SQL 執行速度更快少於 10s,那是因為優化器基於代價的原則並不等價於執行速度的快慢;
b. 再看執行計劃中的 type:index,"index" 代表 「全索引掃描」,其實和全表掃描差不多,只是掃描的時候是按照索引次序進行而不是行,主要優點就是避免了排序,但是開銷仍然非常大。
Extra:Using where 也意味著掃描完索引後還需要回表進行篩選。一般來說,得保證 type 至少達到 range 級別,最好能達到 ref。
在第 2 點中提到的「慢日誌記錄Rows_examined: 1161559,看起來是全表掃描」,這里更正為「全索引掃描」,掃描行數確實等於表的行數;
c. 關於執行計劃中:「rows:644」,其實這個只是估算值,並不準確,我們分析慢 SQL 時判斷准確的掃描行數應該以 slow log 中的 Rows_examined 為准。
4. 優化建議:添加組合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
優化過程:
TASK_DATE 欄位存在索引,但是選擇度很低,優化器不會走這個索引,建議後續可以刪除這個索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在這個 sql 中 REL_DEVID 欄位從命名上看選擇度較高,通過下面 sql 來檢驗確實如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由於有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 組合選擇度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在測試環境添加 REL_DEVID,TASK_ID 組合索引,測試 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引後執行計劃:
這里還要注意一點「隱式轉換」:REL_DEVID 欄位數據類型為 varchar,需要在 sql 中加引號:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
執行時間從 10s+ 降到 毫秒級別:
1 row in set (0.00 sec)
結論
一個典型的 order by 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。
⑻ SQL聚集索引和非聚集索引的區別
聚集索引:也稱 Clustered Index。是指關系表記錄的物理順序與索引的邏輯順序相同。由於一張表只能按照一種物理順序存放,一張表最多也只能存在一個聚集索引。與非聚集索引相比,聚集索引有著更快的檢索速度。
MySQL 里只有 INNODB 表支持聚集索引,INNODB 表數據本身就是聚集索引,也就是常說 IOT,索引組織表。非葉子節點按照主鍵順序存放,葉子節點存放主鍵以及對應的行記錄。所以對 INNODB 表進行全表順序掃描會非常快。
非聚集索引:也叫 Secondary Index。指的是非葉子節點按照索引的鍵值順序存放,葉子節點存放索引鍵值以及對應的主鍵鍵值。MySQL 里除了 INNODB 表主鍵外,其他的都是二級索引。MYISAM,memory 等引擎的表索引都是非聚集索引。簡單點說,就是索引與行數據分開存儲。一張表可以有多個二級索引。
關鍵詞:愛可生、開源資料庫、數據監測、資料庫運維
⑼ sql使用復合索引要注意什麼
sql復合索引一定要注意搜索條件的設置。
還有就是看你用的是什麼資料庫,mysql和oracle,sqlserver都有各自的設定,需要自己去學