索引運演算法
1. c語言火c++中的索引運算符是什麼意思求指教!!!(越詳細越好)
你是想問 * 是什麼意思吧
這是c裡面的指針描述符和解引用符
例子
char *p;
char a;
p = &a;
*p = 'A';
現在a裡面已經儲存 A 了
還有 c/c++ 里沒有索引運算符,是不是你看錯了
2. 資料庫中的hash索引的相關計算,請高手給予解答,謝謝!
索引的意義
·索引在資料庫中的作用相當於目錄在書籍中的作用類似,都用來提高查找信息的速度。
·索引是一個表中所包含值的列表,其中註明了表中包含各個值的行所在的存儲位置,使用索引查找數據時,先從索引對象中獲得相關列的存儲位置,然後再直接去其存儲位置查找所需信息,這樣就無需對這個表進行掃描,從而可以快速的找到所需數據。
3. 索引怎麼建立使用
Create Relational Index
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON <object> ( column [ ASC | DESC ] [ ,...n ] )
[ INCLUDE ( column_name [ ,...n ] ) ]
[ WHERE <filter_predicate> ]
[ WITH ( <relational_index_option> [ ,...n ] ) ]
[ ON { partition_scheme_name ( column_name )
| filegroup_name
| default
}
]
[ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]
參數
UNIQUE
為表或視圖創建唯一索引。唯一索引不允許兩行具有相同的索引鍵值。視圖的聚集索引必須唯一。
無論 IGNORE_DUP_KEY 是否設置為 ON,資料庫引擎都不允許為已包含重復值的列創建唯一索引。否則,資料庫引擎會顯示錯誤消息。必須先刪除重復值,然後才能為一列或多列創建唯一索引。唯一索引中使用的列應設置為 NOT NULL,因為在創建唯一索引時,會將多個 Null 值視為重復值。
CLUSTERED
創建索引時,鍵值的邏輯順序決定表中對應行的物理順序。聚集索引的底層(或稱葉級別)包含該表的實際數據行。一個表或視圖只允許同時有一個聚集索引。
具有唯一聚集索引的視圖稱為索引視圖。為一個視圖創建唯一聚集索引會在物理上具體化該視圖。必須先為視圖創建唯一聚集索引,然後才能為該視圖定義其他索引。
在創建任何非聚集索引之前創建聚集索引。創建聚集索引時會重新生成表中現有的非聚集索引。
如果沒有指定 CLUSTERED,則創建非聚集索引。
注意:
因為按照定義,聚集索引的葉級別與其數據頁相同,所以創建聚集索引和使用 ON partition_scheme_name 或 ON filegroup_name 子句實際上會將表從創建該表時所在的文件組移到新的分區方案或文件組中。對特定的文件組創建表或索引之前,應確認哪些文件組可用並且有足夠的空間供索引使用。
NONCLUSTERED
創建一個指定表的邏輯排序的索引。對於非聚集索引,數據行的物理排序獨立於索引排序。
無論是使用 PRIMARY KEY 和 UNIQUE 約束隱式創建索引,還是使用 CREATE INDEX 顯式創建索引。每個表都最多可包含 999 個非聚集索引。
對於索引視圖,只能為已定義唯一聚集索引的視圖創建非聚集索引。
默認值為 NONCLUSTERED。
index_name
索引的名稱。索引名稱在表或視圖中必須唯一,但在資料庫中不必唯一。索引名稱必須符合標識符的規則。
column
索引所基於的一列或多列。指定兩個或多個列名,可為指定列的組合值創建組合索引。在 table_or_view_name 後的括弧中,按排序優先順序列出組合索引中要包括的列。
一個組合索引鍵中最多可組合 16 列。組合索引鍵中的所有列必須在同一個表或視圖中。組合索引值允許的最大大小為 900 位元組。
不能將大型對象 (LOB) 數據類型 ntext、text、varchar(max)、 nvarchar(max)、varbinary(max)、xml 或 image 的列指定為索引的鍵列。另外,即使 CREATE INDEX 語句中並未引用 ntext、text 或 image 列,視圖定義中也不能包含這些列。
如果 CLR 用戶定義類型支持二進制排序,則可以為該類型的列創建索引。另外,對於已定義為用戶定義類型列的方法調用的計算列,只要這些方法標記為確定性方法且不執行數據訪問操作,便可為該計算列創建索引。
[ ASC | DESC ]
確定特定索引列的升序或降序排序方向。默認值為 ASC。
INCLUDE ( column [ ,...n ] )
指定要添加到非聚集索引的葉級別的非鍵列。非聚集索引可以唯一,也可以不唯一。
在 INCLUDE 列表中列名不能重復,且不能同時用於鍵列和非鍵列。
除 text、ntext 和 image 之外,允許所有數據類型。如果指定的任一非鍵列屬於 varchar(max)、nvarchar(max) 或 varbinary(max) 數據類型,則必須離線 (ONLINE = OFF) 創建或重新生成該索引。
精確或不精確的確定性計算列都可以是包含列。從 image、ntext、text、varchar(max)、nvarchar(max)、varbinary(max) 和 xml 數據類型派生的計算列可以包含在非鍵列中,前提是允許將這些計算列數據類型作為包含列。
WHERE <filter_predicate>
通過指定索引中要包含哪些行來創建篩選索引。篩選索引必須是對表的非聚集索引。為篩選索引中的數據行創建篩選統計信息。
篩選謂詞使用簡單比較邏輯且不能引用計算列、UDT 列、空間數據類型列或 hierarchyID 數據類型列。比較運算符不允許使用 NULL 文本的比較。請改用 IS NULL 和 IS NOT NULL 運算符。
下面是 Proction.BillOfMaterials 表的篩選謂詞的一些示例:
WHERE StartDate > '20000101' AND EndDate <= '20000630'
WHERE ComponentID IN (533, 324, 753)
WHERE StartDate IN ('20000404', '20000905') AND EndDate IS NOT NULL
篩選索引不適用於 XML 索引和全文索引。對於 UNIQUE 索引,僅選定的行必須具有唯一的索引值。篩選索引不允許有 IGNORE_DUP_KEY 選項。
ON partition_scheme_name ( column_name )
指定分區方案,該方案定義要將分區索引的分區映射到的文件組。必須通過執行 CREATE PARTITION SCHEME 或 ALTER PARTITION SCHEME,使資料庫中存在該分區方案。column_name 指定將作為分區索引的分區依據的列。該列必須與 partition_scheme_name 使用的分區函數參數的數據類型、長度和精度相匹配。column_name 不限於索引定義中的列。除了在對 UNIQUE 索引分區時,必須從用作唯一鍵的列中選擇 column_name 外,還可以指定基表中的任何列。通過此限制,資料庫引擎可驗證單個分區中的鍵值唯一性。
注意:
在對非唯一的聚集索引進行分區時,如果尚未指定分區依據列,則默認情況下資料庫引擎將在聚集索引鍵列表中添加分區依據列。在對非唯一的非聚集索引進行分區時,如果尚未指定分區依據列,則資料庫引擎會添加分區依據列作為索引的非鍵(包含)列。
如果未指定 partition_scheme_name 或 filegroup 且該表已分區,則索引會與基礎表使用相同分區依據列並被放入同一分區方案中。
有關將索引分區的詳細信息,請參閱已分區索引的特殊指導原則。
ON filegroup_name
為指定文件組創建指定索引。如果未指定位置且表或視圖尚未分區,則索引將與基礎表或視圖使用相同的文件組。該文件組必須已存在。
ON "default"
為默認文件組創建指定索引。
在此上下文中,「default」不是關鍵字。它是默認文件組的標識符,並且必須進行分隔(類似於 ON "default" 或 ON[default])。如果指定了 "default",則當前會話的 QUOTED_IDENTIFIER 選項必須為 ON。這是默認設置。
[ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]
在創建聚集索引時,指定表的 FILESTREAM 數據的位置。FILESTREAM_ON 子句用於將 FILESTREAM 數據移動到不同的 FILESTREAM 文件組或分區方案。
filestream_filegroup_name 是 FILESTREAM 文件組的名稱。該文件組必須包含一個使用 CREATE DATABASE 或 ALTER DATABASE 語句為該文件組定義的文件;否則,將引發錯誤。
如果表已分區,則必須包含 FILESTREAM_ON 子句並且必須指定 FILESTREAM 文件組的分區方案,且此分區方案需使用與該表分區方案相同的分區函數和分區列。否則將引發錯誤。
如果該表未分區,則無法對 FILESTREAM 列分區。該表的 FILESTREAM 數據必須存儲在一個由 FILESTREAM_ON 子句指定的文件組中。
如果創建的是聚集索引且該表不包含 FILESTREAM 列,則可在 CREATE INDEX 語句中指定 FILESTREAM_ON NULL。
4. mysql索引有幾種
Mysql目前主要有以下幾種索引類型:FULLTEXT,HASH,BTREE,RTREE。
那麼,這幾種索引有什麼功能和性能上的不同呢?
FULLTEXT
即為全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不過目前只有 CHAR、VARCHAR ,TEXT 列上可以創建全文索引。值得一提的是,在數據量較大時候,現將數據放入一個沒有全局索引的表中,然後再用CREATE INDEX創建FULLTEXT索引,要比先為一張表建立FULLTEXT然後再將數據寫入的速度快很多。
全文索引並不是和MyISAM一起誕生的,它的出現是為了解決WHERE name LIKE 「%word%"這類針對文本的模糊查詢效率較低的問題。在沒有全文索引之前,這樣一個查詢語句是要進行遍歷數據表操作的,可見,在數據量較大時是極其的耗時的,如果沒有非同步IO處理,進程將被挾持,很浪費時間,當然這里不對非同步IO作進一步講解,想了解的童鞋,自行谷哥。
全文索引的使用方法並不復雜:
創建ALTER TABLE table ADD INDEX `FULLINDEX` USING FULLTEXT(`cname1`[,cname2…]);
使用SELECT * FROM table WHERE MATCH(cname1[,cname2…]) AGAINST ('word' MODE );
其中, MODE為搜尋方式(IN BOOLEAN MODE ,IN NATURAL LANGUAGE MODE ,IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION / WITH QUERY EXPANSION)。
關於這三種搜尋方式,愚安在這里也不多做交代,簡單地說,就是,布爾模式,允許word里含一些特殊字元用於標記一些具體的要求,如+表示一定要有,-表示一定沒有,*表示通用匹配符,是不是想起了正則,類似吧;自然語言模式,就是簡單的單詞匹配;含表達式的自然語言模式,就是先用自然語言模式處理,對返回的結果,再進行表達式匹配。
對搜索引擎稍微有點了解的同學,肯定知道分詞這個概念,FULLTEXT索引也是按照分詞原理建立索引的。西文中,大部分為字母文字,分詞可以很方便的按照空格進行分割。但很明顯,中文不能按照這種方式進行分詞。那又怎麼辦呢?這個向大家介紹一個Mysql的中文分詞插件Mysqlcft,有了它,就可以對中文進行分詞,想了解的同學請移步Mysqlcft,當然還有其他的分詞插件可以使用。
HASH
Hash這個詞,可以說,自打我們開始碼的那一天起,就開始不停地見到和使用到了。其實,hash就是一種(key=>value)形式的鍵值對,如數學中的函數映射,允許多個key對應相同的value,但不允許一個key對應多個value。正是由於這個特性,hash很適合做索引,為某一列或幾列建立hash索引,就會利用這一列或幾列的值通過一定的演算法計算出一個hash值,對應一行或幾行數據(這里在概念上和函數映射有區別,不要混淆)。在java語言中,每個類都有自己的hashcode()方法,沒有顯示定義的都繼承自object類,該方法使得每一個對象都是唯一的,在進行對象間equal比較,和序列化傳輸中起到了很重要的作用。hash的生成方法有很多種,足可以保證hash碼的唯一性,例如在MongoDB中,每一個document都有系統為其生成的唯一的objectID(包含時間戳,主機散列值,進程PID,和自增ID)也是一種hash的表現。額,我好像扯遠了-_-!
由於hash索引可以一次定位,不需要像樹形索引那樣逐層查找,因此具有極高的效率。那為什麼還需要其他的樹形索引呢?
在這里愚安就不自己總結了。引用下園子里其他大神的文章:來自 14的路 的MySQL的btree索引和hash索引的區別
(1)Hash 索引僅僅能滿足"=","IN"和"<=>"查詢,不能使用范圍查詢。
由於 Hash 索引比較的是進行 Hash 運算之後的 Hash 值,所以它只能用於等值的過濾,不能用於基於范圍的過濾,因為經過相應的 Hash 演算法處理之後的 Hash 值的大小關系,並不能保證和Hash運算前完全一樣。
(2)Hash 索引無法被用來避免數據的排序操作。
由於 Hash 索引中存放的是經過 Hash 計算之後的 Hash 值,而且Hash值的大小關系並不一定和 Hash 運算前的鍵值完全一樣,所以資料庫無法利用索引的數據來避免任何排序運算;
(3)Hash 索引不能利用部分索引鍵查詢。
對於組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合並後再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。
(4)Hash 索引在任何時候都不能避免表掃描。
前面已經知道,Hash 索引是將索引鍵通過 Hash 運算之後,將 Hash運算結果的 Hash 值和所對應的行指針信息存放於一個 Hash 表中,由於不同索引鍵存在相同 Hash 值,所以即使取滿足某個 Hash 鍵值的數據的記錄條數,也無法從 Hash 索引中直接完成查詢,還是要通過訪問表中的實際數據進行相應的比較,並得到相應的結果。
(5)Hash 索引遇到大量Hash值相等的情況後性能並不一定就會比B-Tree索引高。
對於選擇性比較低的索引鍵,如果創建 Hash 索引,那麼將會存在大量記錄指針信息存於同一個 Hash 值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表數據的訪問,而造成整體性能低下。
愚安我稍作補充,講一下HASH索引的過程,順便解釋下上面的第4,5條:
當我們為某一列或某幾列建立hash索引時(目前就只有MEMORY引擎顯式地支持這種索引),會在硬碟上生成類似如下的文件:
hash值 存儲地址
1db54bc745a1 77#45b5
4bca452157d4 76#4556,77#45cc…
…
hash值即為通過特定演算法由指定列數據計算出來,磁碟地址即為所在數據行存儲在硬碟上的地址(也有可能是其他存儲地址,其實MEMORY會將hash表導入內存)。
這樣,當我們進行WHERE age = 18 時,會將18通過相同的演算法計算出一個hash值==>在hash表中找到對應的儲存地址==>根據存儲地址取得數據。
所以,每次查詢時都要遍歷hash表,直到找到對應的hash值,如(4),數據量大了之後,hash表也會變得龐大起來,性能下降,遍歷耗時增加,如(5)。
BTREE
BTREE索引就是一種將索引值按一定的演算法,存入一個樹形的數據結構中,相信學過數據結構的童鞋都對當初學習二叉樹這種數據結構的經歷記憶猶新,反正愚安我當時為了軟考可是被這玩意兒好好地折騰了一番,不過那次考試好像沒怎麼考這個。如二叉樹一樣,每次查詢都是從樹的入口root開始,依次遍歷node,獲取leaf。
BTREE在MyISAM里的形式和Innodb稍有不同
在 Innodb里,有兩種形態:一是primary key形態,其leaf node里存放的是數據,而且不僅存放了索引鍵的數據,還存放了其他欄位的數據。二是secondary index,其leaf node和普通的BTREE差不多,只是還存放了指向主鍵的信息.
而在MyISAM里,主鍵和其他的並沒有太大區別。不過和Innodb不太一樣的地方是在MyISAM里,leaf node里存放的不是主鍵的信息,而是指向數據文件里的對應數據行的信息.
RTREE
RTREE在mysql很少使用,僅支持geometry數據類型,支持該類型的存儲引擎只有MyISAM、BDb、InnoDb、NDb、Archive幾種。
相對於BTREE,RTREE的優勢在於范圍查找.
各種索引的使用情況
(1)對於BTREE這種Mysql默認的索引類型,具有普遍的適用性
(2)由於FULLTEXT對中文支持不是很好,在沒有插件的情況下,最好不要使用。其實,一些小的博客應用,只需要在數據採集時,為其建立關鍵字列表,通過關鍵字索引,也是一個不錯的方法,至少愚安我是經常這么做的。
(3)對於一些搜索引擎級別的應用來說,FULLTEXT同樣不是一個好的處理方法,Mysql的全文索引建立的文件還是比較大的,而且效率不是很高,即便是使用了中文分詞插件,對中文分詞支持也只是一般。真要碰到這種問題,Apache的Lucene或許是你的選擇。
(4)正是因為hash表在處理較小數據量時具有無可比擬的素的優勢,所以hash索引很適合做緩存(內存資料庫)。如mysql資料庫的內存版本Memsql,使用量很廣泛的緩存工具Mencached,NoSql資料庫redis等,都使用了hash索引這種形式。當然,不想學習這些東西的話Mysql的MEMORY引擎也是可以滿足這種需求的。
(5)至於RTREE,愚安我至今還沒有使用過,它具體怎麼樣,我就不知道了。有RTREE使用經歷的同學,到時可以交流下!
5. 什麼叫索引索引的作用和分類
1.
b-tree索引
oracle資料庫中最常見的索引類型是b-tree索引,也就是b-樹索引,以其同名的計算科學結構命名。create
index語句時,默認就是在創建b-tree索引。沒有特別規定可用於任何情況。
2.
點陣圖索引(bitmap
index)
點陣圖索引特定於該列只有幾個枚舉值的情況,比如性別欄位,標示欄位比如只有0和1的情況。
3.
基於函數的索引
比如經常對某個欄位做查詢的時候是帶函數操作的,那麼此時建一個函數索引就有價值了。
4.
分區索引和全局索引
這2個是用於分區表的時候。前者是分區內索引,後者是全表索引
5.
反向索引(reverse)
這個索引不常見,但是特定情況特別有效,比如一個varchar(5)位欄位(員工編號)含值
(10001,10002,10033,10005,10016..)
這種情況默認索引分布過於密集,不能利用好伺服器的並行
但是反向之後10001,20001,33001,50001,61001就有了一個很好的分布,能高效的利用好並行運算。
6.hash索引
hash索引可能是訪問資料庫中數據的最快方法,但它也有自身的缺點。集群鍵上不同值的數目必須在創建hash集群之前就要知道。需要在創建hash集群的時候指定這個值。使用hash索引必須要使用hash集群。
6. 什麼是正向索引什麼是倒排索引鏈接關系計算怎麼算
倒排索引表中的每一項都包括一個屬性值和具有該屬性值的各記錄的地址。由於不是由記錄來確定屬性值,而是由屬性值來確定記錄的位置,因而稱為倒排索引(inverted index)。帶有倒排索引的文件我們稱為倒排索引文件,簡稱倒排文件。建立全文索引中有兩項非常重要,一個是如何對文本進行分詞,一是建立索引的數據結構。分詞的方法基本上是二元分詞法、最大匹配法和統計方法。索引的數據結構基本上採用倒排索引的結構。
分詞的好壞關繫到查詢的准確程度和生成的索引的大小。在中文分詞發展中,早期經常使用分詞方式是二元分詞法,該方法的基本原理是將包含中文的句子進行二元分割,不考慮單詞含義,只對二元單詞進行索引。因此該方法所分出的單詞數量較多,從而產生的索引數量巨大,查詢中會將無用的數據檢索出來,好處是演算法簡單不會漏掉檢索的數據。之後又發展出最大匹配分詞方法,該方法又分為正向最大分詞和逆向最大分詞。其原理和查字典類似,對常用單詞生成一個詞典,分析句子的過程中最大的匹配字典中的單詞,從而將句子拆分為有意義的單詞鏈。最大匹配法中正向分詞方法對偏正式詞語的分辨容易產生錯誤,比如「首飾和服裝」會將「和服」作為單詞分出。達夢資料庫採用的是改進的逆向最大分詞方法,該分詞方法較正向正確率有所提高。最為復雜的是通過統計方式進行分詞的方法。該方法採用隱式馬爾科夫鏈,也就是後一個單詞出現的概率依靠於前一個單詞出現的概率,最後統計所有單詞出現的概率的最大為分詞的依據。這個方法對新名詞和地名的識別要遠遠高於最大匹配法,准確度隨著取樣文本的數量的增大而提高。
二元分詞方法和統計方法是不依賴於詞典的,而最大匹配法分詞方法是依賴於詞典的,詞典的內容決定分詞結構的好壞。
全文檢索的索引被稱為倒排索引,之所以成為倒排索引,是因為將每一個單詞作為索引項,根據該索引項查找包含該單詞的文本。因此,索引都是單詞和唯一記錄文本的標示是一對多的關系。將索引單詞排序,根據排序後的單詞定位包含該單詞的文本。
7. 索引順序查找演算法
索引查找是在索引表和主表(即線性表的索引存儲結構)上進行的查找。索引查找的過程是:首先根據給定的索引值K1,在索引表上查找出索引值等於KI的索引項,以確定對應予表在主表中的開始位置和長度,然後再根據給定的關鍵字K2,茬對應的子表中查找出關鍵字等於K2的元素(結點)。對索引表或子表進行查找時,若表是順序存儲的有序表,則既可進行順序查找,也可進行二分查找,否則只能進行順序查找。
設數組A是具有mainlist類型的一個主表,數組B是具有inde)dist類型的在主表A 上建立的一個索引表,m為索引表B的實際長度,即所含的索引項的個數,KI和K2分別為給定待查找的索引值和關鍵字(當然它們的類型應分別為索引表中索引值域的類型和主表中關鍵字域在索引存儲中,不僅便於查找單個元素,而且更便於查找一個子表中的全部元素。當需要對一個子袁中的全部元素依次處理時,只要從索引表中查找出該子表的開始位置即可。由此開始位置可以依次取出該子表中的每一個元素,所以整個查找過程的時間復雜度為,若不是採用索引存儲,而是採用順序存儲,即使把它組織成有序表而進行二分查找時,索引查找一個子表中的所有元素與二分查找一個子表中的所有元素相比。
若在主表中的每個子表後都預留有空閑位置,則索引存儲也便於進行插入和刪除運算,因為其運算過程只涉及到索引表和相應的子表,只需要對相應子表中的元素進行比較和移動,與其它任何子表無關,不像順序表那樣需涉及到整個表中的所有元素,即牽一發而動全身。
在線性表的索引存儲結構上進行插入和刪除運算的演算法,也同查找演算法類似,其過程為:首先根據待插入或刪除元素的某個域(假定子表就是按照此域的值劃分的)的值查找索引表,確定出對應的子表,然後再根據待插入或刪除元素的關鍵字,在該子表中做插入或刪除元素的操作。因為每個子表不是順序存儲,就是鏈接存儲,所以對它們做插入或刪除操作都是很簡單的。
不知道答案與兄台的問題是否一致,也是網上找的,不對請見諒哈~~
8. MySQL資料庫的索引的操作知多少
MySQL索引類型包括:
(1)普通索引
這是最基本的索引,它沒有任何限制。它有以下幾種創建方式:
◆創建索引
CREATE INDEX indexName ON mytable(username(length)); 如果是CHAR,VARCHAR類型,length可以小於欄位實際長度;如果是BLOB和TEXT類型,必須指定 length,下同。
◆修改表結構
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;
(2)唯一索引
與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創建方式:
◆創建索引
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)) );
(3)主鍵索引
它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時創建主鍵索引:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) ); 當然也可以用 ALTER 命令。記住:一個表只能有一個主鍵。
(4)組合索引
為了形象地對比單列索引和組合索引,為表添加多個欄位:
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); 建表時,usernname長度為 16,這里用 10。這是因為一般情況下名字的長度不會超過10,這樣會加速索引查詢速度,還會減少索引文件的大小,提高INSERT的更新速度。
如果分別在 usernname,city,age上建立單列索引,讓該表有3個單列索引,查詢時和上述的組合索引效率也會大不一樣,遠遠低於我們的組合索引。雖然此時有了三個索引,但MySQL只能用到其中的那個它認為似乎是最有效率的單列索引。
建立這樣的組合索引,其實是相當於分別建立了下面三組組合索引:
usernname,city,age usernname,city usernname 為什麼沒有 city,age這樣的組合索引呢?這是因為MySQL組合索引「最左前綴」的結果。簡單的理解就是只從最左面的開始組合。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個SQL就會用到這個組合索引:
SELECT * FROM mytable WHREE username="admin" AND city="鄭州" SELECT * FROM mytable WHREE username="admin" 而下面幾個則不會用到:
SELECT * FROM mytable WHREE age=20 AND city="鄭州" SELECT * FROM mytable WHREE city="鄭州"
(5)建立索引的時機
一般來說,在WHERE和JOIN中出現的列需要建立索引,但也不完全如此,因為MySQL只對<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE才會使用索引。例如:
SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username WHERE m.age=20 AND m.city='鄭州' 此時就需要對city和age建立索引,由於mytable表的userame也出現在了JOIN子句中,也有對它建立索引的必要。
剛才提到只有某些時候的LIKE才需建立索引。因為在以通配符%和_開頭作查詢時,MySQL不會使用索引。例如下句會使用索引:
SELECT * FROM mytable WHERE username like'admin%' 而下句就不會使用:
SELECT * FROM mytable WHEREt Name like'%admin' 因此,在使用LIKE時應注意以上的區別。
(6)索引的不足之處
上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:
◆雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。
◆建立索引會佔用磁碟空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快。
索引只是提高效率的一個因素,如果你的MySQL有大數據量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。
(7)使用索引的注意事項
使用索引時,有以下一些技巧和注意事項:
◆索引不會包含有NULL值的列
只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那麼這一列對於此復合索引就是無效的。所以我們在資料庫設計時不要讓欄位的默認值為NULL。
◆使用短索引
對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10個或20個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。
◆索引列排序
MySQL查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。
◆like語句操作
一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like 「%aaa%」 不會使用索引而like 「aaa%」可以使用索引。
◆不要在列上進行運算
select * from users where YEAR(adddate)<2007; 將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成
select * from users where adddate<『2007-01-01』;
◆不使用NOT IN和<>操作
9. 談談您對索引的理解,舉例說明索引的使用經驗
如果有時候要寫一個計算量比較大的通用方法時候,裡面能計算的都是通過索引來的。索引有什麼好處?索引就是基本通過數值運算就能找到指定的內存地址。
如果採用其他文字來尋找
,除了循環數組之外(循環本身也是計算計算尋找內存地址的方式),還要進行值匹對,如果匹對成功了,才返回這個對象。
從這里就可嘩搐糕誹蕹賭革澀宮績以知道,如果一開始就知道索引值的話,就能很快提取出當前對象來。
但是索引在大型程序也有不方便的地方。例如:很影響邏輯結構。因為你不知道你所指代索引代表的具體含義。
但是一個方法進行了封裝之後,你就可以不用考慮這么多。你只需管這個方法夠效率
夠健壯,調理清晰。只管東西扔進去
就能出來一個你想要的東西的程度。而裡面能採用高效的方法就高效。
總之索引是個好東西,大部分數組操作
都會轉換為索引結構的。
10. 一個軟考題目,索引計算,要說明理由啊,不然不給分啰。
每個磁碟塊 →512B
塊號(每條邏輯號和物理號映射的記錄)占→3B
一級索引時:512/3=170個邏輯號(即170個物理塊)170×512B/1024=85KB
二級索引時:170×170×512B/1024=14450KB
索引的選擇性算:select(distinct 欄位)/count(*) from 表;值從小到大,越接近1越好。
(10)索引運演算法擴展閱讀:
空間范圍的每一級劃分原理就是通過規則劃分(矩形或正方形)將索引區域劃分為不重疊的許多子空間(矩形或正方形),對於該索引區域建立一個范圍索引表,記錄每個子空間的范圍、劃分的級別和子空間索引表名稱;對每個子空間單元再按照以上規則進行再次劃分;
對於最後一級的子空間,則為每個子空間單元建立一個子空間索引表,存儲落在這個子空間之內的空間要素標識、外包絡矩形;並且對於最後一級的子空間,如果包含的空間要素個數太多,可直接將該子空間物理分割成多個。