MySQL優(yōu)化筆記(三)--索引的使用、原理和設(shè)計(jì)優(yōu)化

之前的文章一直在規(guī)避索引的建立去優(yōu)化數(shù)據(jù)庫,不是不想講,而是這個(gè)太重要,必須抽出來講。今天我們就來研究下數(shù)據(jù)庫索引的設(shè)計(jì)與優(yōu)化(MySQL為例)。

文章結(jié)構(gòu):(1)索引的概述和使用;(2)索引的基本原理;(3)索引分類;(4)索引設(shè)計(jì)優(yōu)化

本系列demo下載

(一)MySQL優(yōu)化筆記(一)--庫與表基本操作以及數(shù)據(jù)增刪改

(二)MySQL優(yōu)化筆記(二)--查找優(yōu)化(1)(非索引設(shè)計(jì))

(三)MySQL優(yōu)化筆記(二)--查找優(yōu)化(2)(外連接、多表聯(lián)合查詢以及查詢注意點(diǎn))

(四) MySQL優(yōu)化筆記(三)--索引的使用、原理和設(shè)計(jì)優(yōu)化

(五) MySQL優(yōu)化筆記(四)--表的設(shè)計(jì)與優(yōu)化(單表、多表)

(六)MySQL優(yōu)化筆記(五)--數(shù)據(jù)庫存儲(chǔ)引擎

(七)MySQL優(yōu)化筆記(六)--存儲(chǔ)過程和存儲(chǔ)函數(shù)

(八)MySQL優(yōu)化筆記(七)--視圖應(yīng)用詳解

(九) MySQL優(yōu)化筆記(八)--鎖機(jī)制超詳細(xì)解析(鎖分類、事務(wù)并發(fā)、引擎并發(fā)控制)

文章目錄:

(1)索引的概述和使用

概述

-? 什么是索引

-? 索引的優(yōu)點(diǎn)

-? 索引的缺點(diǎn)

-? 為什么需要索引

索引的使用(語法)

-? 創(chuàng)建索引:(三種方式)

-? 刪除索引

-? 查看索引

(2)索引的基本原理

整體性原理例子

針對(duì)存儲(chǔ)性質(zhì)講解

索引的數(shù)據(jù)結(jié)構(gòu):B+tree

B+tree性質(zhì)

B+tree有兩種搜索方法

(3)索引分類

普通索引

唯一索引

主鍵索引

全文索引:(FULLTEXT)

單列索引與多列索引(其實(shí)是相當(dāng)于一個(gè)用法技巧)(重點(diǎn))

-? 單列索引

-? 多列索引

-? 聚集索引和非聚集索引

-? 聚集索引

-? 非聚集索引

-? 關(guān)于聚集索引以及非聚集索引的幾個(gè)問題

(4)索引設(shè)計(jì)優(yōu)化:

索引建立的幾大原則

索引使用的注意點(diǎn)(大概有14點(diǎn))

一、索引的概述和使用:

(1)概述:

1)什么是索引?

索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。更通俗的說,數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。在沒有索引的情況下,數(shù)據(jù)庫會(huì)遍歷全部數(shù)據(jù)后選擇符合條件的;而有了相應(yīng)的索引之后,數(shù)據(jù)庫會(huì)直接在索引中查找符合條件的選項(xiàng)。

索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。更通俗的說,數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。在沒有索引的情況下,數(shù)據(jù)庫會(huì)遍歷全部數(shù)據(jù)后選擇符合條件的;而有了相應(yīng)的索引之后,數(shù)據(jù)庫會(huì)直接在索引中查找符合條件的選項(xiàng)。

索引的性質(zhì)分類:

索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對(duì)于單行的檢索很快。

2)索引的優(yōu)點(diǎn):

一】通過創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性。

二】可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。

三】可以加速表和表之間的連接,特別是在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。

四】在使用分組和排序 子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢中分組和排序的時(shí)間。

五】通過使用索引,可以在查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。

3)索引的缺點(diǎn):

一】創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間,這種時(shí)間隨著數(shù)據(jù)量的增加而增加。

二】索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個(gè)索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會(huì)更大。

三】當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行增加、刪除和修改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù),這樣就降低了數(shù)據(jù)的維護(hù)速度。

4)為什么需要索引:

數(shù)據(jù)在磁盤上是以塊的形式存儲(chǔ)的。為確保對(duì)磁盤操作的原子性,訪問數(shù)據(jù)的時(shí)候會(huì)一并訪問所有數(shù)據(jù)塊。磁盤上的這些數(shù)據(jù)塊與鏈表類似,即它們都包含一個(gè)數(shù)據(jù)段和一個(gè)指針,指針指向下一個(gè)節(jié)點(diǎn)(數(shù)據(jù)塊)的內(nèi)存地址,而且它們都不需要連續(xù)存儲(chǔ)(即邏輯上相鄰的數(shù)據(jù)塊在物理上可以相隔很遠(yuǎn))。

鑒于很多記錄只能做到按一個(gè)字段排序,所以要查詢某個(gè)未經(jīng)排序的字段,就需要使用線性查找,即要訪問N/2個(gè)數(shù)據(jù)塊,其中N指的是一個(gè)表所涵蓋的所有數(shù)據(jù)塊。如果該字段是非鍵字段(也就是說,不包含唯一值),那么就要搜索整個(gè)表空間,即要訪問全部N個(gè)數(shù)據(jù)塊。(在某些情況下,索引可以避免排序操作。)

然而,對(duì)于經(jīng)過排序的字段,可以使用二分查找,因此只要訪問log2 N個(gè)數(shù)據(jù)塊。同樣,對(duì)于已經(jīng)排過序的非鍵字段,只要找到更大的值,也就不用再搜索表中的其他數(shù)據(jù)塊了。這樣一來,性能就會(huì)有實(shí)質(zhì)性的提升。

(2)索引的使用(語法):本文代碼實(shí)例的針對(duì)此數(shù)據(jù)庫

一】創(chuàng)建索引:(三種方式)

第一種方式:

//第一種方式://在執(zhí)行CREATE TABLE 時(shí)創(chuàng)建索引:(硬設(shè)一個(gè)id索引)CREATE TABLE `black_list` (? ? `id` BIGINT(20) NOTNULLAUTO_INCREMENT,? ? `black_user_id` BIGINT(20)NULLDEFAULTNULL,? ? `user_id` BIGINT(20)NULLDEFAULTNULL,? ? PRIMARY KEY (`id`)? ? INDEX indexName (black_user_id(length)))COLLATE='utf8_general_ci'ENGINE=InnoDB;

第二種方式:使用ALTER TABLE命令去增加索引:

ALTER TABLE用來創(chuàng)建普通索引、UNIQUE索引或PRIMARY KEY索引。

//標(biāo)準(zhǔn)語句:ALTER TABLE table_name ADD INDEXindex_name(column_list)//添加普通索引,索引值可出現(xiàn)多次。 ALTER TABLE table_name ADDUNIQUE(column_list)//這條語句創(chuàng)建的索引的值必須是唯一的(除了NULL外,NULL可能會(huì)出現(xiàn)多次)。 ALTER TABLE table_name ADD PRIMARYKEY(column_list)//該語句添加一個(gè)主鍵,這意味著索引值必須是唯一的,且不能為NULL。ALTER TABLE table_name ADD FULLTEXTindex_name(olumu_name);該語句指定了索引為FULLTEXT,用于全文索引。//針對(duì)上述數(shù)據(jù)庫,增加商品分類的索引ALTER table commodity_list ADD INDEXclassify_index(Classify_Description)

其中table_name是要增加索引的表名,column_list指出對(duì)哪些列進(jìn)行索引,多列時(shí)各列之間用逗號(hào)分隔。索引名index_name可自己命名,缺省時(shí),MySQL將根據(jù)第一個(gè)索引列賦一個(gè)名稱。另外,ALTER TABLE允許在單個(gè)語句中更改多個(gè)表,因此可以在同時(shí)創(chuàng)建多個(gè)索引。

第三種方式:使用CREATE INDEX命令創(chuàng)建

CREATE INDEX可對(duì)表增加普通索引或UNIQUE索引。

//標(biāo)準(zhǔn)語句:CREATE INDEX index_name ONtable_name(column_list)CREATE UNIQUE INDEX index_name ONtable_name(column_list)//針對(duì)上述數(shù)據(jù)庫:CREATE INDEX classify_index? ONcommodity_list(Classify_Description)

table_name、index_name和column_list具有與ALTER TABLE語句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語句創(chuàng)建PRIMARY KEY索引。

二】刪除索引:

刪除索引可以使用ALTER TABLE或DROP INDEX語句來實(shí)現(xiàn)。DROP INDEX可以在ALTER TABLE內(nèi)部作為一條語句處理,其格式如下:

DROP INDEX [indexName] ON [table_name];alter table [table_name] drop index [index_name] ;alter table [table_name] drop primary key ;//針對(duì)上述數(shù)據(jù)庫drop index classify_index on commodity_list ;

其中,在前面的兩條語句中,都刪除了table_name中的索引index_name。而在最后一條語句中,只在刪除PRIMARY KEY索引中使用,因?yàn)橐粋€(gè)表只可能有一個(gè)PRIMARY KEY索引,因此不需要指定索引名。如果沒有創(chuàng)建PRIMARY KEY索引,但表具有一個(gè)或多個(gè)UNIQUE索引,則MySQL將刪除第一個(gè)UNIQUE索引。

如果從表中刪除某列,則索引會(huì)受影響。對(duì)于多列組合的索引,如果刪除其中的某列,則該列也會(huì)從索引中刪除。如果刪除組成索引的所有列,則整個(gè)索引將被刪除。

三】查看索引:

SHOWINDEXFROM[table_name];showkeysfrom[table_name];

這里寫圖片描述

Table:表的名稱。

Non_unique:如果索引不能包括重復(fù)詞,則為0。如果可以,則為1。

Key_name:索引的名稱。

Seq_in_index:索引中的列序列號(hào),從1開始。

Column_name:列名稱。

Collation:列以什么方式存儲(chǔ)在索引中。在MySQL中,有值‘A'(升序)或NULL(無分類)。

Cardinality:索引中唯一值的數(shù)目的估計(jì)值。通過運(yùn)行ANALYZE TABLE或myisamchk -a可以更新。基數(shù)根據(jù)被存儲(chǔ)為整數(shù)的統(tǒng)計(jì)數(shù)據(jù)來計(jì)數(shù),所以即使對(duì)于小型表,該值也沒有必要是精確的。基數(shù)越大,當(dāng)進(jìn)行聯(lián)合時(shí),MySQL使用該索引的機(jī)會(huì)就越大。

Sub_part:如果列只是被部分地編入索引,則為被編入索引的字符的數(shù)目。如果整列被編入索引,則為NULL。

Packed:指示關(guān)鍵字如何被壓縮。如果沒有被壓縮,則為NULL。

Null:如果列含有NULL,則含有YES。如果沒有,則該列含有NO。

Index_type:用過的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

Comment:注釋

二、索引的基本原理:

舉例解析基本原理:

整體性原理例子:

除了詞典,生活中隨處可見索引的例子,如火車站的車次表、圖書的目錄等。它們的原理都是一樣的,通過不斷的縮小想要獲得數(shù)據(jù)的范圍來篩選出最終想要的結(jié)果,同時(shí)把隨機(jī)的事件變成順序的事件,也就是我們總是通過同一種查找方式來鎖定數(shù)據(jù)。

SQL的應(yīng)用場(chǎng)景會(huì)使用索引:

數(shù)據(jù)庫也是一樣,但顯然要復(fù)雜許多,因?yàn)椴粌H面臨著等值查詢,還有范圍查詢(>、<、between、in)、模糊查詢(like)、并集查詢(or)等等。數(shù)據(jù)庫應(yīng)該選擇怎么樣的方式來應(yīng)對(duì)所有的問題呢?我們回想字典的例子,能不能把數(shù)據(jù)分成段,然后分段查詢呢?最簡(jiǎn)單的如果1000條數(shù)據(jù),1到100分成第一段,101到200分成第二段,201到300分成第三段......這樣查第250條數(shù)據(jù),只要找第三段就可以了,一下子去除了90%的無效數(shù)據(jù)。

針對(duì)存儲(chǔ)性質(zhì)講解:此部分轉(zhuǎn)載自此博主此博客

由于存儲(chǔ)介質(zhì)的特性,磁盤本身存取就比主存慢很多,再加上機(jī)械運(yùn)動(dòng)耗費(fèi),磁盤的存取速度往往是主存的幾百分分之一,因此為了提高效率,要盡量減少磁盤I/O。為了達(dá)到這個(gè)目的,磁盤往往不是嚴(yán)格按需讀取,而是每次都會(huì)預(yù)讀,即使只需要一個(gè)字節(jié),磁盤也會(huì)從這個(gè)位置開始,順序向后讀取一定長度的數(shù)據(jù)放入內(nèi)存。這樣做的理論依據(jù)是計(jì)算機(jī)科學(xué)中著名的局部性原理:當(dāng)一個(gè)數(shù)據(jù)被用到時(shí),其附近的數(shù)據(jù)也通常會(huì)馬上被使用。程序運(yùn)行期間所需要的數(shù)據(jù)通常比較集中。

由于磁盤順序讀取的效率很高(不需要尋道時(shí)間,只需很少的旋轉(zhuǎn)時(shí)間),因此對(duì)于具有局部性的程序來說,預(yù)讀可以提高I/O效率。

預(yù)讀的長度一般為頁(page)的整倍數(shù)。頁是計(jì)算機(jī)管理存儲(chǔ)器的邏輯塊,硬件及操作系統(tǒng)往往將主存和磁盤存儲(chǔ)區(qū)分割為連續(xù)的大小相等的塊,每個(gè)存儲(chǔ)塊稱為一頁(在許多操作系統(tǒng)中,頁得大小通常為4k),主存和磁盤以頁為單位交換數(shù)據(jù)。當(dāng)程序要讀取的數(shù)據(jù)不在主存中時(shí),會(huì)觸發(fā)一個(gè)缺頁異常,此時(shí)系統(tǒng)會(huì)向磁盤發(fā)出讀盤信號(hào),磁盤會(huì)找到數(shù)據(jù)的起始位置并向后連續(xù)讀取一頁或幾頁載入內(nèi)存中,然后異常返回,程序繼續(xù)運(yùn)行。

索引的數(shù)據(jù)結(jié)構(gòu):B+tree此處部分轉(zhuǎn)載自此博主此博客

這里寫圖片描述

B樹:關(guān)于B樹的相關(guān),以后我會(huì)詳細(xì)更新在此文檔

B樹中每個(gè)節(jié)點(diǎn)包含了鍵值和鍵值對(duì)于的數(shù)據(jù)對(duì)象存放地址指針,所以成功搜索一個(gè)對(duì)象可以不用到達(dá)樹的葉節(jié)點(diǎn)。

成功搜索包括節(jié)點(diǎn)內(nèi)搜索和沿某一路徑的搜索,成功搜索時(shí)間取決于關(guān)鍵碼所在的層次以及節(jié)點(diǎn)內(nèi)關(guān)鍵碼的數(shù)量。

在B樹中查找給定關(guān)鍵字的方法是:首先把根結(jié)點(diǎn)取來,在根結(jié)點(diǎn)所包含的關(guān)鍵字K1,…,kj查找給定的關(guān)鍵字(可用順序查找或二分查找法),若找到等于給定值的關(guān)鍵字,則查找成功;否則,一定可以確定要查的關(guān)鍵字在某個(gè)Ki或Ki+1之間,于是取Pi所指的下一層索引節(jié)點(diǎn)塊繼續(xù)查找,直到找到,或指針Pi為空時(shí)查找失敗。

B+tree性質(zhì):

1.)n棵子tree的節(jié)點(diǎn)包含n個(gè)關(guān)鍵字,不用來保存數(shù)據(jù)而是保存數(shù)據(jù)的索引。

2.)所有的葉子結(jié)點(diǎn)中包含了全部關(guān)鍵字的信息,及指向含這些關(guān)鍵字記錄的指針,且葉子結(jié)點(diǎn)本身依關(guān)鍵字的大小自小而大順序鏈接。

3.)所有的非終端結(jié)點(diǎn)可以看成是索引部分,結(jié)點(diǎn)中僅含其子樹中的最大(或最小)關(guān)鍵字。

B+樹非葉節(jié)點(diǎn)中存放的關(guān)鍵碼并不指示數(shù)據(jù)對(duì)象的地址指針,非葉節(jié)點(diǎn)只是索引部分。所有的葉節(jié)點(diǎn)在同一層上,包含了全部關(guān)鍵碼和相應(yīng)數(shù)據(jù)對(duì)象的存放地址指針,且葉節(jié)點(diǎn)按關(guān)鍵碼從小到大順序鏈接。如果實(shí)際數(shù)據(jù)對(duì)象按加入的順序存儲(chǔ)而不是按關(guān)鍵碼次數(shù)存儲(chǔ)的話,葉節(jié)點(diǎn)的索引必須是稠密索引,若實(shí)際數(shù)據(jù)存儲(chǔ)按關(guān)鍵碼次序存放的話,葉節(jié)點(diǎn)索引時(shí)稀疏索引。

B+ 樹中,數(shù)據(jù)對(duì)象的插入和刪除僅在葉節(jié)點(diǎn)上進(jìn)行。

B+樹有2個(gè)頭指針,一個(gè)是樹的根節(jié)點(diǎn),一個(gè)是最小關(guān)鍵碼的葉節(jié)點(diǎn)。

B+tree有兩種搜索方法:

1)一種是按葉節(jié)點(diǎn)自己拉起的鏈表順序搜索。

2)一種是從根節(jié)點(diǎn)開始搜索,和B樹類似,不過如果非葉節(jié)點(diǎn)的關(guān)鍵碼等于給定值,搜索并不停止,而是繼續(xù)沿右指針,一直查到葉節(jié)點(diǎn)上的關(guān)鍵碼。所以無論搜索是否成功,都將走完樹的所有層。

這兩種處理索引的數(shù)據(jù)結(jié)構(gòu)的不同之處:(B和B+樹)

1)B樹中同一鍵值不會(huì)出現(xiàn)多次,并且它有可能出現(xiàn)在葉結(jié)點(diǎn),也有可能出現(xiàn)在非葉結(jié)點(diǎn)中。而B+樹的鍵一定會(huì)出現(xiàn)在葉結(jié)點(diǎn)中,并且有可能在非葉結(jié)點(diǎn)中也有可能重復(fù)出現(xiàn),以維持B+樹的平衡。

2)因?yàn)锽樹鍵位置不定,且在整個(gè)樹結(jié)構(gòu)中只出現(xiàn)一次,雖然可以節(jié)省存儲(chǔ)空間,但使得在插入、刪除操作復(fù)雜度明顯增加。B+樹相比來說是一種較好的折中。

3)B樹的查詢效率與鍵在樹中的位置有關(guān),最大時(shí)間復(fù)雜度與B+樹相同(在葉結(jié)點(diǎn)的時(shí)候),最小時(shí)間復(fù)雜度為1(在根結(jié)點(diǎn)的時(shí)候)。而B+樹的時(shí)候復(fù)雜度對(duì)某建成的樹是固定的。

這里寫圖片描述

上圖展示了一種可能的索引方式。左邊是數(shù)據(jù)表,一共有兩列七條記錄,最左邊的是數(shù)據(jù)記錄的物理地址(注意邏輯上相鄰的記錄在磁盤上也并不是一定物理相鄰的)。為了加快Col2的查找,可以維護(hù)一個(gè)右邊所示的二叉查找樹,每個(gè)節(jié)點(diǎn)分別包含索引鍵值和一個(gè)指向?qū)?yīng)數(shù)據(jù)記錄物理地址的指針,這樣就可以運(yùn)用二叉查找在O(log2n)的復(fù)雜度內(nèi)獲取到相應(yīng)數(shù)據(jù)。

三、索引分類:

一)普通索引:

基本的索引,它沒有任何限制。

創(chuàng)建方式:

//標(biāo)準(zhǔn)語句:ALTER TABLE table_name ADD INDEXindex_name(column_list)CREATE INDEX index_name ONtable_name(column_list);//還有建表的時(shí)候創(chuàng)建亦可CREATE TABLEtable_name( ID INT NOT NULL, column_listVARCHAR(16)NOT NULL,INDEX [index_name ](column_list(length)) );

如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長度;如果是BLOB和TEXT類型,必須指定 length。

例子:假如length為10,也就是索引這個(gè)字段的記錄的前10個(gè)字符。

二)唯一索引:

與前面的普通索引類似,不同的就是:MySQL數(shù)據(jù)庫索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。

它有以下幾種創(chuàng)建方式:

ALTER TABLE table_name ADD UNIQUE (column_list)CREATE UNIQUE INDEX index_name ON table_name (column_list)//還有建表時(shí)創(chuàng)建CREATE TABLE table_name ( ID INT NOTNULL,? column_list VARCHAR(16) NOTNULL,? UNIQUE [index_name ]? (column_list(length))? );

三)主鍵索引:

它是一種特殊的唯一索引,不允許有空值。一般是在建表的時(shí)候同時(shí)創(chuàng)建主鍵索引:

CREATE TABLE table_name ( ID INT NOTNULL, [column] VARCHAR(16) NOTNULL, PRIMARY KEY(ID)? );

四)全文索引:(FULLTEXT)

定義:

全文檢索是對(duì)大數(shù)據(jù)文本進(jìn)行索引,在建立的索引中對(duì)要查找的單詞進(jìn)行進(jìn)行搜索,定位哪些文本數(shù)據(jù)包括要搜索的單詞。因此,全文檢索的全部工作就是建立索引和在索引中搜索定位,所有的工作都是圍繞這兩個(gè)來進(jìn)行的。

此索引關(guān)鍵:

建立全文索引中有兩項(xiàng)非常重要,一個(gè)是如何對(duì)文本進(jìn)行分詞,一是建立索引的數(shù)據(jù)結(jié)構(gòu)。分詞的方法基本上是二元分詞法、最大匹配法和統(tǒng)計(jì)方法。索引的數(shù)據(jù)結(jié)構(gòu)基本上采用倒排索引的結(jié)構(gòu)。分詞的好壞關(guān)系到查詢的準(zhǔn)確程度和生成的索引的大小。

應(yīng)用:

FULLTEXT索引僅可用于 MyISAM 表;他們可以從CHAR、VARCHAR或TEXT列中作為CREATE TABLE語句的一部分被創(chuàng)建,或是隨后使用ALTER TABLE 或CREATE INDEX被添加。

但是要注意:對(duì)于較大的數(shù)據(jù)集,將你的資料輸入一個(gè)沒有FULLTEXT索引的表中,然后創(chuàng)建索引,其速度比把資料輸入現(xiàn)有FULLTEXT索引的速度更為快。不過切記對(duì)于大容量的數(shù)據(jù)表,生成全文索引是一個(gè)非常消耗時(shí)間非常消耗硬盤空間的做法。因?yàn)椋。〔迦胄薷膭h除表的同時(shí)也要針對(duì)索引做一系列的處理。

創(chuàng)建方法:

//針對(duì)content做了全文索引:CREATE TABLE `table` (`id`int(11) NOTNULLAUTO_INCREMENT ,`title`char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOTNULL,`content` text CHARACTER SET utf8 COLLATE utf8_general_ciNULL,PRIMARY KEY (`id`),FULLTEXT (content));

SQL使用全文索引的方法:首先必須是MyISAM的數(shù)據(jù)庫引擎的數(shù)據(jù)表

如果是其他數(shù)據(jù)引擎,則全文索引不會(huì)生效。

SELECT * FROM article WHERE MATCH( content) AGAINST('想查詢的字符串')

此外,MySQL自帶的全文索引只能對(duì)英文進(jìn)行全文檢索,目前無法對(duì)中文進(jìn)行全文檢索。如果需要對(duì)包含中文在內(nèi)的文本數(shù)據(jù)進(jìn)行全文檢索,我們需要采用Sphinx(斯芬克斯)/Coreseek技術(shù)來處理中文。

注意:

目前,使用MySQL自帶的全文索引時(shí),如果查詢字符串的長度過短將無法得到期望的搜索結(jié)果。MySQL全文索引所能找到的詞的默認(rèn)最小長度為4個(gè)字符。另外,如果查詢的字符串包含停止詞,那么該停止詞將會(huì)被忽略。

如果可能,請(qǐng)盡量先創(chuàng)建表并插入所有數(shù)據(jù)后再創(chuàng)建全文索引,而不要在創(chuàng)建表時(shí)就直接創(chuàng)建全文索引,因?yàn)榍罢弑群笳叩娜乃饕室摺?/p>

五)單列索引與多列索引(其實(shí)是相當(dāng)于一個(gè)用法技巧)

單列索引,就是平常的只索引一個(gè)一個(gè)的字段的方式

//例子為name列的頭10個(gè)字符創(chuàng)建一個(gè)索引:CREATE TABLEtest(name CHAR(200)NOT NULL,KEYindex_name(name(10)));

多列索引(也叫組合索引)

相關(guān)概念(適用多列索引的原因):

MySQL能在多個(gè)列上創(chuàng)建索引。一個(gè)索引可以由最多15個(gè)列組成。(在CHAR和VARCHAR列上,你也可以使用列的前綴作為一個(gè)索引的部分)。

一個(gè)多重列索引可以認(rèn)為是包含通過合并(concatenate)索引列值創(chuàng)建的值的一個(gè)排序數(shù)組。

多個(gè)單列索引與單個(gè)多列索引的查詢效果不同,因?yàn)閳?zhí)行查詢時(shí),MySQL只能使用一個(gè)索引,會(huì)從多個(gè)單列索引中選擇一個(gè)限制最為嚴(yán)格(獲得結(jié)果集記錄數(shù)最少)的索引。

當(dāng)你為在一個(gè)WHERE子句索引的第一列指定已知的數(shù)量時(shí),MySQL以這種方式使用多重列索引使得查詢非常快速,即使你不為其他列指定值。

適用場(chǎng)景

1.全字段匹配

2.匹配部分最左前綴

3.匹配第一列

4.匹配第一列范圍查詢(可用用like a%,但不能使用like %b)

5.精確匹配某一列和和范圍匹配另外一列

例子:

//假設(shè)只使用單列索引名字ALTER TABLE people ADD INDEXname(name);//使用多列索引:ALTER TABLE people ADD INDEXheight_name_age(height,name,age);//相當(dāng)于創(chuàng)建了(height)單列索引,(height,name)組合索引以及(height,name,age)組合索引/*

注意:

注:在mysql中執(zhí)行查詢時(shí),只能使用一個(gè)索引,如果我們?cè)趎ame,age上分別建索引,執(zhí)行查詢時(shí),只能使用一個(gè)索引,mysql會(huì)選擇一個(gè)最嚴(yán)格(獲得結(jié)果集記錄數(shù)最少)的索引。

*/

注意:

在創(chuàng)建多列索引時(shí),要根據(jù)業(yè)務(wù)需求,where子句中使用最頻繁的一列放在最左邊。

組合索引(多列索引)的原則:

原則:

最左前綴:顧名思義,就是最左優(yōu)先

平時(shí)用的SQL查詢語句一般都有比較多的限制條件,所以為了進(jìn)一步榨取MySQL的效率,就要考慮建立組合索引(多列索引)。例如上面使用的例子就相當(dāng)于創(chuàng)建了(height)單列索引,(height,name)組合索引以及(height,name,age)組合索引。

此外,補(bǔ)充一個(gè)概念對(duì)比,那就是聚集索引和非聚集索引:

1)聚集索引相關(guān)概念說法取自此處

定義:

該索引中鍵值的邏輯順序決定了表中相應(yīng)行的物理順序。

聚集索引確定表中數(shù)據(jù)的物理順序。聚集索引類似于電話簿,后者按姓氏排列數(shù)據(jù)。由于聚集索引規(guī)定數(shù)據(jù)在表中的物理存儲(chǔ)順序,因此一個(gè)表只能包含一個(gè)聚集索引。但該索引可以包含多個(gè)列(組合索引),就像電話簿按姓氏和名字進(jìn)行組織一樣。

注意事項(xiàng):

定義聚集索引鍵時(shí)使用的列越少越好。

使用的場(chǎng)景:

一)包含大量非重復(fù)值的列。

二)使用下列運(yùn)算符返回一個(gè)范圍值的查詢:BETWEEN、>、>=、< 和 <=。

三)被連續(xù)訪問的列。

四)返回大型結(jié)果集的查詢。

五)經(jīng)常被使用聯(lián)接或 GROUP BY 子句的查詢?cè)L問的列;一般來說,這些是外鍵列。對(duì) ORDER BY 或 GROUP BY 子句中指定的列進(jìn)行索引,可以使 SQL Server 不必對(duì)數(shù)據(jù)進(jìn)行排序,因?yàn)檫@些行已經(jīng)排序。這樣可以提高查詢性能。

六)OLTP 類型的應(yīng)用程序,這些程序要求進(jìn)行非常快速的單行查找(一般通過主鍵)。

缺點(diǎn)請(qǐng)看此博客

不適用于:

頻繁更改的列 。這將導(dǎo)致整行移動(dòng)(因?yàn)?SQL Server 必須按物理順序保留行中的數(shù)據(jù)值)。這一點(diǎn)要特別注意,因?yàn)樵诖髷?shù)據(jù)量事務(wù)處理系統(tǒng)中數(shù)據(jù)是易失的。

寬鍵 。來自聚集索引的鍵值由所有非聚集索引作為查找鍵使用,因此存儲(chǔ)在每個(gè)非聚集索引的葉條目內(nèi)。

2)非聚集索引:

定義:

數(shù)據(jù)存儲(chǔ)在一個(gè)地方,索引存儲(chǔ)在另一個(gè)地方,索引帶有指針指向數(shù)據(jù)的存儲(chǔ)位置。

非聚集索引中的項(xiàng)目按索引鍵值的順序存儲(chǔ),而表中的信息按另一種順序存儲(chǔ)(這可以由聚集索引規(guī)定)。對(duì)于非聚集索引,可以為在表非聚集索引中查找數(shù)據(jù)時(shí)常用的每個(gè)列創(chuàng)建一個(gè)非聚集索引。有些書籍包含多個(gè)索引。例如,一本介紹園藝的書可能會(huì)包含一個(gè)植物通俗名稱索引,和一個(gè)植物學(xué)名索引,因?yàn)檫@是讀者查找信息的兩種最常用的方法。

兩者的區(qū)別此處有個(gè)很清晰的例子:請(qǐng)點(diǎn)此處

選擇使用的場(chǎng)景:

這里寫圖片描述

關(guān)于聚集索引以及非聚集索引的幾個(gè)問題:

一)聚集索引的約束是唯一性,是否要求字段也是唯一的呢?

一般我們指定一個(gè)表的主鍵,如果這個(gè)表之前沒有聚集索引,同時(shí)建立主鍵時(shí)候沒有強(qiáng)制指定使用非聚集索引,SQL會(huì)默認(rèn)在此字段上創(chuàng)建一個(gè)聚集索引,而主鍵都是唯一的,所以理所當(dāng)然的認(rèn)為創(chuàng)建聚集索引的字段也需要唯一。

聚集索引可以創(chuàng)建在任何一列你想創(chuàng)建的字段上,這是從理論上講,實(shí)際情況并不能隨便指定,否則在性能上會(huì)是惡夢(mèng)。

二)|主鍵就是聚集索引???

這樣有時(shí)會(huì)對(duì)聚集索引的一種浪費(fèi)。Innodb將通過主鍵聚集數(shù)據(jù),如果沒有定義主鍵,Innodb會(huì)選擇第一個(gè)非空的唯一索引代替,如果沒有非空唯一索引,Innodb會(huì)隱式定義一個(gè)6字節(jié)的rowid主鍵來作為聚集索引。innodb只聚集在同一個(gè)頁面中的記錄,包含相鄰鍵值的頁面可能會(huì)相距甚遠(yuǎn)。

因?yàn)槊總€(gè)表中只能有一個(gè)聚集索引的規(guī)則,這使得聚集索引變得更加珍貴。

使用聚集索引的最大好處就是能夠根據(jù)查詢要求,迅速縮小查詢范圍,避免全表掃描。在實(shí)際應(yīng)用中,因?yàn)?ID號(hào)是自動(dòng)生成的,我們并不知道每條記錄的ID號(hào),所以我們很難在實(shí)踐中用ID號(hào)來進(jìn)行查詢。這就使讓ID號(hào)這個(gè)主鍵作為聚集索引成為一種資源浪費(fèi)。其次,讓每個(gè)ID號(hào)都不同的字段作為聚集索引也不符合“大數(shù)目的不同值情況下不應(yīng)建立聚合索引”規(guī)則;當(dāng)然,這種情況只是針對(duì)用戶經(jīng)常修改記錄內(nèi)容,特別是索引項(xiàng)的時(shí)候會(huì)負(fù)作用,但對(duì)于查詢速度并沒有影響。

三)是不是聚集索引就一定要比非聚集索引性能優(yōu)呢???

如果想查詢學(xué)分在60-90之間的學(xué)生的學(xué)分以及姓名,在學(xué)分上創(chuàng)建聚集索引是否是最優(yōu)的呢?

答:否。既然只輸出兩列,我們可以在學(xué)分以及學(xué)生姓名上創(chuàng)建聯(lián)合非聚集索引(也就是多列索引),此時(shí)的索引就形成了覆蓋索引,即索引所存儲(chǔ)的內(nèi)容就是最終輸出的數(shù)據(jù),這種索引在比以學(xué)分為聚集索引做查詢性能更好。

四)在數(shù)據(jù)庫中通過什么描述聚集索引與非聚集索引的?

索引是通過二叉樹的形式進(jìn)行描述的,我們可以這樣區(qū)分聚集與非聚集索引的區(qū)別:聚集索引的葉節(jié)點(diǎn)就是最終的數(shù)據(jù)節(jié)點(diǎn),而非聚集索引的葉節(jié)仍然是索引節(jié)點(diǎn),但它有一個(gè)指向最終數(shù)據(jù)的指針。

五)在主鍵是創(chuàng)建聚集索引的表在數(shù)據(jù)插入上為什么比主鍵上創(chuàng)建非聚集索引表速度要慢?

在有主鍵的表中插入數(shù)據(jù)行,由于有主鍵唯一性的約束,所以需要保證插入的數(shù)據(jù)沒有重復(fù)。我們來比較下主鍵為聚集索引和非聚集索引的查找情況:聚集索引由于索引葉節(jié)點(diǎn)就是數(shù)據(jù)頁,所以如果想檢查主鍵的唯一性,需要遍歷所有數(shù)據(jù)節(jié)點(diǎn)才行,但非聚集索引不同,由于非聚集索引上已經(jīng)包含了主鍵值,所以查找主鍵唯一性,只需要遍歷所有的索引頁就行,這比遍歷所有數(shù)據(jù)行減少了不少IO消耗。這就是為什么主鍵上創(chuàng)建非聚集索引比主鍵上創(chuàng)建聚集索引在插入數(shù)據(jù)時(shí)要快的真正原因。

四、索引設(shè)計(jì)優(yōu)化:

(1)索引建立的幾大原則:

1)最左前綴匹配原則,非常重要的原則,mysql會(huì)一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整。

2)=和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優(yōu)化器會(huì)幫你優(yōu)化成索引可以識(shí)別的形式。

3)盡量選擇區(qū)分度高的列作為索引,區(qū)分度的公式是count(distinct col)/count(*),表示字段不重復(fù)的比例,比例越大我們掃描的記錄數(shù)越少,唯一鍵的區(qū)分度是1,而一些狀態(tài)、性別字段可能在大數(shù)據(jù)面前區(qū)分度就是0,那可能有人會(huì)問,這個(gè)比例有什么經(jīng)驗(yàn)值嗎?使用場(chǎng)景不同,這個(gè)值也很難確定,一般需要join的字段我們都要求是0.1以上,即平均1條掃描10條記錄

4)索引列不能參與計(jì)算,保持列“干凈”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡(jiǎn)單,b+樹中存的都是數(shù)據(jù)表中的字段值,但進(jìn)行檢索時(shí),需要把所有元素都應(yīng)用函數(shù)才能比較,顯然成本太大。所以語句應(yīng)該寫成create_time = unix_timestamp(’2014-05-29’);

5)盡量的擴(kuò)展索引,不要新建索引。比如表中已經(jīng)有a的索引,現(xiàn)在要加(a,b)的索引,那么只需要修改原來的索引即可。

6)定義有外鍵的數(shù)據(jù)列一定要建立索引。

7)對(duì)于那些查詢中很少涉及的列,重復(fù)值比較多的列不要建立索引。

8)對(duì)于定義為text、image和bit的數(shù)據(jù)類型的列不要建立索引。

9)對(duì)于經(jīng)常存取的列避免建立索引

(2)索引使用的注意點(diǎn):

一、)一般說來,索引應(yīng)建立在那些將用于JOIN,WHERE判斷和ORDER BY排序的字段上。盡量不要對(duì)數(shù)據(jù)庫中某個(gè)含有大量重復(fù)的值的字段建立索引。對(duì)于一個(gè)ENUM類型的字段來說,出現(xiàn)大量重復(fù)值是很有可能的情況。

二、)應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:

select idfromt where num isnull

最好不要給數(shù)據(jù)庫留NULL,盡可能的使用 NOT NULL填充數(shù)據(jù)庫.

備注、描述、評(píng)論之類的可以設(shè)置為 NULL,其他的,最好不要使用NULL。

不要以為 NULL 不需要空間,比如:char(100) 型,在字段建立時(shí),空間就固定了, 不管是否插入值(NULL也包含在內(nèi)),都是占用 100個(gè)字符的空間的,如果是varchar這樣的變長字段, null 不占用空間。

可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值,然后這樣查詢:

三、)應(yīng)盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描。

四、)應(yīng)盡量避免在 where 子句中使用 or 來連接條件,如果一個(gè)字段有索引,一個(gè)字段沒有索引,將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:

select idfromt where num=10orName ='fuzhu'

可以這樣查詢,充分利用索引:

select id from twherenum = 10union allselect id from twhereName ='fuzhu'

五、)in 和 not in 也要慎用,否則會(huì)導(dǎo)致全表掃描。

select id from twherenumin(1,2,3)

對(duì)于連續(xù)的數(shù)值,能用 between 就不要用 in 了:

select idfromt where num between1and3

很多時(shí)候用 exists 代替 in 是一個(gè)好的選擇

select numfroma where numin(select numfromb)

正上面的,用下面的語句替換:

select num from awhereexists(select 1 from bwherenum=a.num)

六、)下面的模糊查詢也將導(dǎo)致全表掃描:

select id from twherename like ‘%abc%’

一般情況下不鼓勵(lì)使用like操作,如果非使用不可,如何使用也是一個(gè)問題。like “%aaa%” 不會(huì)使用索引,而like “aaa%”可以使用索引。

若要提高效率,可以考慮全文檢索。

既然談到模糊查詢下使用索引,我們就順便詳細(xì)地講講吧。

1.? like %keyword? ? 索引失效,使用全表掃描。但可以通過翻轉(zhuǎn)函數(shù)+like前模糊查詢+建立翻轉(zhuǎn)函數(shù)索引=走翻轉(zhuǎn)函數(shù)索引,不走全表掃描。例子在此處

2.? like keyword%? ? 索引有效。

3.? like %keyword% 索引失效,也無法使用反向索引。

//可以拿我給出的數(shù)據(jù)庫試一下嘛。然后用explain測(cè)試,就能測(cè)出有沒有走索引了select *fromtable where code like'Classify_Description%'select *fromtable where code like'%Classify_Description%'select *fromtable where code like'%Classify_Description'

七、)如果在 where 子句中使用參數(shù),也會(huì)導(dǎo)致全表掃描。因?yàn)镾QL只有在運(yùn)行時(shí)才會(huì)解析局部變量,但優(yōu)化程序不能將訪問計(jì)劃的選擇推遲到運(yùn)行時(shí);它必須在編譯時(shí)進(jìn)行選擇。然 而,如果在編譯時(shí)建立訪問計(jì)劃,變量的值還是未知的,因而無法作為索引選擇的輸入項(xiàng)。如下面語句將進(jìn)行全表掃描:

select id from twherenum = @num

可以改為強(qiáng)制查詢使用索引:

select id from twith(index(索引名)) where num=@num

應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行表達(dá)式操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:

select id from twherenum/2 = 100

正上面的應(yīng)改為:

select id from twherenum = 100*2

八、)應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:

select id from t wheresubstring(name,1,3)= ’abc’//name以abc開頭的idselect id from t wheredatediff(day,createdate,’2005-11-30′)=0-–‘2005-11-30’//生成的id

應(yīng)改為:

select idfromt where name like'abc%'select idfromt where createdate >='2005-11-30'andcreatedate <'2005-12-1'

九、).不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無法正確使用索引。

十、)在使用索引字段作為條件時(shí),如果該索引是復(fù)合索引(多列索引),那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引,否則該索引將不會(huì)被使用,并且應(yīng)盡可能的讓字段順序與索引順序相一致。

十一、)索引并不是越多越好,索引固然可以提高相應(yīng)的 select 的效率,但同時(shí)也降低了 insert 及 update 的效率,因?yàn)?insert 或 update 時(shí)有可能會(huì)重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個(gè)表的索引數(shù)最好不要超過6個(gè),若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有必要。

十二、)應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列,因?yàn)?clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲(chǔ)順序,一旦該列值改變將導(dǎo)致整個(gè)表記錄的順序的調(diào)整,會(huì)耗費(fèi)相當(dāng)大的資源。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應(yīng)將該索引建為 clustered 索引。

十三、)盡量避免向客戶端返回大數(shù)據(jù)量,若數(shù)據(jù)量過大,應(yīng)該考慮相應(yīng)需求是否合理。

十四、)MySQL查詢只使用一個(gè)索引,因此如果where子句中已經(jīng)使用了索引的話,那么order by中的列是不會(huì)使用索引的。因此數(shù)據(jù)庫默認(rèn)排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個(gè)列的排序,如果需要最好給這些列創(chuàng)建復(fù)合索引。

用到的部分例子數(shù)據(jù)庫在里面

好了,MySQL優(yōu)化筆記(三)--索引的使用、原理和設(shè)計(jì)優(yōu)化,這是積累的必經(jīng)一步,我會(huì)繼續(xù)出這個(gè)系列文章,分享經(jīng)驗(yàn)給大家。歡迎在下面指出錯(cuò)誤,共同學(xué)習(xí)!!你的點(diǎn)贊是對(duì)我最好的支持!!

作者:JackFrost_fuzhu

鏈接:http://www.lxweimin.com/p/6b080a787b61

來源:簡(jiǎn)書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,595評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,814評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,224評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,444評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,988評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,804評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,998評(píng)論 1 370
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評(píng)論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,237評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評(píng)論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,706評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,993評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容