「數(shù)據(jù)庫調優(yōu)」屢試不爽的面試連環(huán)combo

點贊再看萨咳,養(yǎng)成習慣懊缺,微信搜索【三太子敖丙】關注這個互聯(lián)網(wǎng)茍且偷生的工具人。

本文 GitHub https://github.com/JavaFamily 已收錄培他,有一線大廠面試完整考點鹃两、資料以及我的系列文章。

前言

面試官:敖丙你簡歷上寫了你會數(shù)據(jù)庫調優(yōu)舀凛,你都是怎么調優(yōu)的俊扳?

敖丙:加索引。

面試官:還有么猛遍?

敖丙:沒了馋记。

面試官:我們公司的門你知道在哪里吧,自己走還是我送你懊烤?

image

哈哈開頭這個場景是我臆想的一個面試場景梯醒,但是大家是不是覺得很真實,每個人的簡歷上但凡寫到了數(shù)據(jù)庫腌紧,都會在后面順便寫一句茸习,會數(shù)據(jù)庫調優(yōu)。

但是問題就來了壁肋,面試官一問到數(shù)據(jù)庫調優(yōu)的逮光,大家就說加索引,除了加索引大家還知道別的么墩划?

或者索引相關的點你全部都知道么涕刚?聚簇索引,非聚簇索引乙帮,普通索引杜漠,唯一索引,change buffer,表鎖驾茴、行鎖盼樟、間隙鎖以及行鎖并發(fā)情況下的最大TPS是多少?還有索引為啥會選擇錯誤锈至?這些大家知道嘛晨缴?

我覺得調優(yōu)能回答的點還是很多很多的,我自己看了《MySQL實戰(zhàn)》、《高性能MySQL》、《丁奇MySQL47講》之后總結了自己去面試回答的一套邏輯贯莺,個人覺得是比較不錯的一套combo绿鸣,這套連招下來曲稼,一般面試官都會暗自對你豎起大拇指,反正我面試的時候基本上就是這一套。

內容就是個人理解的總結,還有書中內容的復述械拍,需要一定的數(shù)據(jù)庫知識,不過我想大家都點進來了装盯,肯定都會了坷虑。

image

正文

數(shù)據(jù)庫調優(yōu)其實一般情況都是我們的SQL調優(yōu),SQL的調優(yōu)就可以解決大部分問題了埂奈,當然也不排除SQL執(zhí)行環(huán)節(jié)的調優(yōu)迄损。

我之前在索引和數(shù)據(jù)庫基礎環(huán)節(jié)有介紹過相關的基礎知識,這里就不過多的贅述了挥转,但是數(shù)據(jù)庫的組成可能很多小伙伴都忘記了,那我們再看一遍結構圖吧共屈。

image

我們所謂的調優(yōu)也就是在绑谣,執(zhí)行器執(zhí)行之前的分析器,優(yōu)化器階段完成的拗引,那我們開發(fā)工作中怎么去調優(yōu)的呢借宵?

帥丙一般在開發(fā)涉及SQL的業(yè)務都會去本地環(huán)境跑一遍SQL,用explain去看一下執(zhí)行計劃矾削,看看分析的結果是否符合自己的預期壤玫,用沒用到相關的索引,然后再去線上環(huán)境跑一下看看執(zhí)行時間(這里只有查詢語句哼凯,修改語句也無法在線上執(zhí)行)欲间。

遇SQL不決explain,但是這里就要說到第一個坑了断部。

排除緩存干擾

因為在MySQL8.0之前我們的數(shù)據(jù)庫是存在緩存這樣的情況的猎贴,我之前就被坑過,因為存在緩存,我發(fā)現(xiàn)我sql怎么執(zhí)行都是很快她渴,當然第一次其實不快但是我沒注意到达址,以至于上線后因為緩存經(jīng)常失效,導致rt(Response time)時高時低趁耗。

后面就發(fā)現(xiàn)了是緩存的問題沉唠,我們在執(zhí)行SQL的時候,記得加上SQL NoCache去跑SQL苛败,這樣跑出來的時間就是真實的查詢時間了满葛。

我說一下為什么緩存會失效,而且是經(jīng)常失效著拭。

如果我們當前的MySQL版本支持緩存而且我們又開啟了緩存纱扭,那每次請求的查詢語句和結果都會以key-value的形式緩存在內存中的,大家也看到我們的結構圖了儡遮,一個請求會先去看緩存是否存在乳蛾,不存在才會走解析器。

緩存失效比較頻繁的原因就是鄙币,只要我們一對表進行更新肃叶,那這個表所有的緩存都會被清空,其實我們很少存在不更新的表十嘿,特別是我之前的電商場景因惭,可能靜態(tài)表可以用到緩存,但是我們都走大數(shù)據(jù)離線分析绩衷,緩存也就沒用了蹦魔。

大家如果是8.0以上的版本就不用擔心這個問題,如果是8.0之下的版本咳燕,記得排除緩存的干擾勿决。

Explain

最開始提到了用執(zhí)行計劃去分析,我想explain是大家SQL調優(yōu)都會回答到的吧招盲。

因為這基本上是寫SQL的必備操作低缩,那我現(xiàn)在問大家一個我去阿里面試被問過的一個問題:explain你記得哪些字段,分別有什么含義曹货?

當時我就回答上來三個咆繁,我默認大家都是有數(shù)據(jù)庫基礎的,所以每個我這里不具體討論每個字段顶籽,怕大家忘記我貼一遍圖大家自己回憶一下玩般。

image

那我再問大家一下,你們認為統(tǒng)計這個統(tǒng)計的行數(shù)就是完全對的么礼饱?索引一定會走到最優(yōu)索引么壤短?

當然我都這么問了设拟,你們肯定也知道結果了,行數(shù)只是一個接近的數(shù)字久脯,不是完全正確的纳胧,索引也不一定就是走最優(yōu)的,是可能走錯的帘撰。

我的總行數(shù)大概有10W行跑慕,但是我去用explain去分析sql的時候,就會發(fā)現(xiàn)只得到了9.4W摧找,為啥行數(shù)只是個近視值呢核行?

image
image

看過基礎章節(jié)的小伙伴都知道,MySQL中數(shù)據(jù)的單位都是頁蹬耘,MySQL又采用了采樣統(tǒng)計的方法芝雪,采樣統(tǒng)計的時候,InnoDB默認會選擇N個數(shù)據(jù)頁综苔,統(tǒng)計這些頁面上的不同值惩系,得到一個平均值,然后乘以這個索引的頁面數(shù)如筛,就得到了這個索引的基數(shù)堡牡。

我們數(shù)據(jù)是一直在變的,所以索引的統(tǒng)計信息也是會變的杨刨,會根據(jù)一個閾值晤柄,重新做統(tǒng)計。

至于MySQL索引可能走錯也很好理解妖胀,如果走A索引要掃描100行芥颈,B所有只要20行,但是他可能選擇走A索引赚抡,你可能會想MySQL是不是有病啊爬坑,其實不是的。

一般走錯都是因為優(yōu)化器在選擇的時候發(fā)現(xiàn)怕品,走A索引沒有額外的代價妇垢,比如走B索引并不能直接拿到我們的值巾遭,還需要回到主鍵索引才可以拿到肉康,多了一次回表的過程,這個也是會被優(yōu)化器考慮進去的灼舍。

他發(fā)現(xiàn)走A索引不需要回表吼和,沒有額外的開銷,所有他選錯了骑素。

如果是上面的統(tǒng)計信息錯了炫乓,那簡單,我們用analyze table tablename 就可以重新統(tǒng)計索引信息了,所以在實踐中末捣,如果你發(fā)現(xiàn)explain的結果預估的rows值跟實際情況差距比較大侠姑,可以采用這個方法來處理。

還有一個方法就是force index強制走正確的索引箩做,或者優(yōu)化SQL莽红,最后實在不行,可以新建索引邦邦,或者刪掉錯誤的索引安吁。

覆蓋索引

上面我提到了,可能需要回表這樣的操作燃辖,那我們怎么能做到不回表呢鬼店?在自己的索引上就查到自己想要的,不要去主鍵索引查了黔龟。

覆蓋索引

如果在我們建立的索引上就已經(jīng)有我們需要的字段妇智,就不需要回表了,在電商里面也是很常見的捌锭,我們需要去商品表通過各種信息查詢到商品id俘陷,id一般都是主鍵,可能sql類似這樣:

select itemId from itemCenter where size between 1 and 6
image

因為商品id itemId一般都是主鍵观谦,在size索引上肯定會有我們這個值拉盾,這個時候就不需要回主鍵表去查詢id信息了。

由于覆蓋索引可以減少樹的搜索次數(shù)豁状,顯著提升查詢性能捉偏,所以使用覆蓋索引是一個常用的性能優(yōu)化手段。

聯(lián)合索引

還是商品表舉例泻红,我們需要根據(jù)他的名稱夭禽,去查他的庫存,假設這是一個很高頻的查詢請求谊路,你會怎么建立索引呢讹躯?

大家可以思考上面的回表的消耗對SQL進行優(yōu)化。

是的建立一個缠劝,名稱和庫存的聯(lián)合索引潮梯,這樣名稱查出來就可以看到庫存了,不需要查出id之后去回表再查詢庫存了惨恭,聯(lián)合索引在我們開發(fā)過程中也是常見的秉馏,但是并不是可以一直建立的,大家要思考索引占據(jù)的空間脱羡。

image

剛才我舉的例子其實有點生硬萝究,正常通過商品名稱去查詢庫存的請求是不多的免都,但是也不代表沒有哈,真來了帆竹,難道我們去全表掃描绕娘?

最左匹配原則

大家在寫sql的時候,最好能利用到現(xiàn)有的SQL最大化利用栽连,像上面的場景业舍,如果利用一個模糊查詢 itemname like ’敖丙%‘,這樣還是能利用到這個索引的升酣,而且如果有這樣的聯(lián)合索引舷暮,大家也沒必要去新建一個商品名稱單獨的索引了。

很多時候我們索引可能沒建對噩茄,那你調整一下順序下面,可能就可以優(yōu)化到整個SQL了。

索引下推

你已經(jīng)知道了前綴索引規(guī)則绩聘,那我就說一個官方幫我們優(yōu)化的東西沥割,索引下推。

select * from itemcenter where name like '敖%' and size=22 and age = 20;

所以這個語句在搜索索引樹的時候凿菩,只能用 “敖”机杜,找到第一個滿足條件的記錄ID1,當然衅谷,這還不錯椒拗,總比全表掃描要好。

然后呢获黔?

當然是判斷其他條件是否滿足蚀苛,比如size。

在MySQL 5.6之前玷氏,只能從ID1開始一個個回表堵未,到主鍵索引上找出數(shù)據(jù)行,再對比字段值盏触。

image

而MySQL 5.6 引入的索引下推優(yōu)化(index condition pushdown)渗蟹, 可以在索引遍歷過程中,對索引中包含的字段先做判斷赞辩,直接過濾掉不滿足條件的記錄雌芽,減少回表次數(shù)。

image

唯一索引普通索引選擇難題

這個在我的面試視頻里面其實問了好幾次了诗宣,核心是需要回答到change buffer膘怕,那change buffer又是個什么東西呢想诅?

當需要更新一個數(shù)據(jù)頁時召庞,如果數(shù)據(jù)頁在內存中就直接更新岛心,而如果這個數(shù)據(jù)頁還沒有在內存中的話,在不影響數(shù)據(jù)一致性的前提下篮灼,InooDB會將這些更新操作緩存在change buffer中忘古,這樣就不需要從磁盤中讀入這個數(shù)據(jù)頁了。

在下次查詢需要訪問這個數(shù)據(jù)頁的時候诅诱,將數(shù)據(jù)頁讀入內存髓堪,然后執(zhí)行change buffer中與這個頁有關的操作,通過這種方式就能保證這個數(shù)據(jù)邏輯的正確性娘荡。

需要說明的是干旁,雖然名字叫作change buffer,實際上它是可以持久化的數(shù)據(jù)炮沐。也就是說争群,change buffer在內存中有拷貝,也會被寫入到磁盤上大年。

將change buffer中的操作應用到原數(shù)據(jù)頁换薄,得到最新結果的過程稱為merge。

除了訪問這個數(shù)據(jù)頁會觸發(fā)merge外翔试,系統(tǒng)有后臺線程會定期merge轻要。在數(shù)據(jù)庫正常關閉(shutdown)的過程中,也會執(zhí)行merge操作垦缅。

image

顯然冲泥,如果能夠將更新操作先記錄在change buffer,減少讀磁盤壁涎,語句的執(zhí)行速度會得到明顯的提升柏蘑。而且,數(shù)據(jù)讀入內存是需要占用buffer pool的粹庞,所以這種方式還能夠避免占用內存咳焚,提高內存利用率

那么,什么條件下可以使用change buffer呢庞溜?

對于唯一索引來說革半,所有的更新操作都要先判斷這個操作是否違反唯一性約束。

要判斷表中是否存在這個數(shù)據(jù)流码,而這必須要將數(shù)據(jù)頁讀入內存才能判斷又官,如果都已經(jīng)讀入到內存了,那直接更新內存會更快漫试,就沒必要使用change buffer了六敬。

因此,唯一索引的更新就不能使用change buffer驾荣,實際上也只有普通索引可以使用外构。

change buffer用的是buffer pool里的內存普泡,因此不能無限增大,change buffer的大小审编,可以通過參數(shù)innodb_change_buffer_max_size來動態(tài)設置撼班,這個參數(shù)設置為50的時候,表示change buffer的大小最多只能占用buffer pool的50%垒酬。

將數(shù)據(jù)從磁盤讀入內存涉及隨機IO的訪問砰嘁,是數(shù)據(jù)庫里面成本最高的操作之一,change buffer因為減少了隨機磁盤訪問勘究,所以對更新性能的提升是會很明顯的矮湘。

change buffer的使用場景

因為merge的時候是真正進行數(shù)據(jù)更新的時刻,而change buffer的主要目的就是將記錄的變更動作緩存下來口糕,所以在一個數(shù)據(jù)頁做merge之前板祝,change buffer記錄的變更越多(也就是這個頁面上要更新的次數(shù)越多),收益就越大走净。

因此券时,對于寫多讀少的業(yè)務來說,頁面在寫完以后馬上被訪問到的概率比較小伏伯,此時change buffer的使用效果最好橘洞,這種業(yè)務模型常見的就是賬單類、日志類的系統(tǒng)说搅。

反過來炸枣,假設一個業(yè)務的更新模式是寫入之后馬上會做查詢,那么即使?jié)M足了條件弄唧,將更新先記錄在change buffer适肠,但之后由于馬上要訪問這個數(shù)據(jù)頁,會立即觸發(fā)merge過程候引。這樣隨機訪問IO的次數(shù)不會減少侯养,反而增加了change buffer的維護代價,所以澄干,對于這種業(yè)務模式來說逛揩,change buffer反而起到了副作用。

前綴索引

我們存在郵箱作為用戶名的情況麸俘,每個人的郵箱都是不一樣的辩稽,那我們是不是可以在郵箱上建立索引,但是郵箱這么長从媚,我們怎么去建立索引呢逞泄?

MySQL是支持前綴索引的,也就是說,你可以定義字符串的一部分作為索引喷众。默認地各谚,如果你創(chuàng)建索引的語句不指定前綴長度,那么索引就會包含整個字符串侮腹。

我們是否可以建立一個區(qū)分度很高的前綴索引,達到優(yōu)化和節(jié)約空間的目的呢稻励?

使用前綴索引父阻,定義好長度,就可以做到既節(jié)省空間望抽,又不用額外增加太多的查詢成本加矛。

上面說過覆蓋索引了,覆蓋索引是不需要回表的煤篙,但是前綴索引斟览,即使你的聯(lián)合索引已經(jīng)包涵了相關信息,他還是會回表辑奈,因為他不確定你到底是不是一個完整的信息苛茂,就算你是www.aobing@mogu.com一個完整的郵箱去查詢,他還是不知道你是否是完整的鸠窗,所以他需要回表去判斷一下妓羊。

下面這個也是我在阿里面試面試官問過我的,很長的字段稍计,想做索引我們怎么去優(yōu)化他呢躁绸?

因為存在一個磁盤占用的問題,索引選取的越長臣嚣,占用的磁盤空間就越大净刮,相同的數(shù)據(jù)頁能放下的索引值就越少,搜索的效率也就會越低硅则。

我當時就回答了一個hash淹父,把字段hash為另外一個字段存起來,每次校驗hash就好了怎虫,hash的索引也不大弹灭。

我們都知道只要區(qū)分度過高,都可以揪垄,那我們可以采用倒序穷吮,或者刪減字符串這樣的情況去建立我們自己的區(qū)分度,不過大家需要注意的是饥努,調用函數(shù)也是一次開銷喲捡鱼,這點當時沒注意。

就比如本來是www.aobing@qq,com 其實前面的www.基本上是沒任何區(qū)分度的酷愧,所有人的郵箱都是這么開頭的驾诈,你一搜一大堆出來缠诅,放在索引還浪費內存,你可以substring()函數(shù)截取掉前面的乍迄,然后建立索引管引。

我們所有人的身份證都是區(qū)域開頭的,同區(qū)域的人很多闯两,那怎么做良好的區(qū)分呢褥伴?REVERSE()函數(shù)翻轉一下,區(qū)分度可能就高了漾狼。

這些操作都用到了函數(shù)重慢,我就說一下函數(shù)的坑。

條件字段函數(shù)操作

日常開發(fā)過程中逊躁,大家經(jīng)常對很多字段進行函數(shù)操作似踱,如果對日期字段操作,浮點字符操作等等稽煤,大家需要注意的是核芽,如果對字段做了函數(shù)計算,就用不上索引了酵熙,這是MySQL的規(guī)定狞洋。

對索引字段做函數(shù)操作,可能會破壞索引值的有序性绿店,因此優(yōu)化器就決定放棄走樹搜索功能吉懊。

需要注意的是,優(yōu)化器并不是要放棄使用這個索引假勿。

這個時候大家可以用一些取巧的方法借嗽,比如 select * from tradelog where id + 1 = 10000 就走不上索引,select * from tradelog where id = 9999就可以转培。

隱式類型轉換

select * from t where id = 1

如果id是字符類型的恶导,1是數(shù)字類型的,你用explain會發(fā)現(xiàn)走了全表掃描浸须,根本用不上索引惨寿,為啥呢?

因為MySQL底層會對你的比較進行轉換删窒,相當于加了 CAST( id AS signed int) 這樣的一個函數(shù)裂垦,上面說過函數(shù)會導致走不上索引。

隱式字符編碼轉換

還是一樣的問題肌索,如果兩個表的字符集不一樣蕉拢,一個是utf8mb4,一個是utf8,因為utf8mb4是utf8的超集晕换,所以一旦兩個字符比較午乓,就會轉換為utf8mb4再比較。

轉換的過程相當于加了CONVERT(id USING utf8mb4)函數(shù)闸准,那又回到上面的問題了益愈,用到函數(shù)就用不上索引了。

還有大家一會可能會遇到mysql突然卡頓的情況夷家,那可能是MySQLflush了蒸其。

flush

redo log大家都知道,也就是我們對數(shù)據(jù)庫操作的日志瘾英,他是在內存中的枣接,每次操作一旦寫了redo log就會立馬返回結果颂暇,但是這個redo log總會找個時間去更新到磁盤缺谴,這個操作就是flush。

在更新之前耳鸯,當內存數(shù)據(jù)頁跟磁盤數(shù)據(jù)頁內容不一致的時候湿蛔,我們稱這個內存頁為“臟頁”。

內存數(shù)據(jù)寫入到磁盤后县爬,內存和磁盤上的數(shù)據(jù)頁的內容就一致了阳啥,稱為“干凈頁“。

那什么時候會flush呢财喳?

  1. InnoDB的redo log寫滿了察迟,這時候系統(tǒng)會停止所有更新操作,把checkpoint往前推進耳高,redo log留出空間可以繼續(xù)寫扎瓶。

  2. 系統(tǒng)內存不足,當需要新的內存頁泌枪,而內存不夠用的時候概荷,就要淘汰一些數(shù)據(jù)頁,空出內存給別的數(shù)據(jù)頁使用碌燕。如果淘汰的是“臟頁”误证,就要先將臟頁寫到磁盤。

你一定會說修壕,這時候難道不能直接把內存淘汰掉愈捅,下次需要請求的時候,從磁盤讀入數(shù)據(jù)頁慈鸠,然后拿redo log出來應用不就行了改鲫?

這里其實是從性能考慮的,如果刷臟頁一定會寫盤,就保證了每個數(shù)據(jù)頁有兩種狀態(tài):

  • 一種是內存里存在像棘,內存里就肯定是正確的結果稽亏,直接返回;
  • 另一種是內存里沒有數(shù)據(jù)缕题,就可以肯定數(shù)據(jù)文件上是正確的結果截歉,讀入內存后返回。
    這樣的效率最高烟零。
  1. MySQL認為系統(tǒng)“空閑”的時候瘪松,只要有機會就刷一點“臟頁”。

  2. MySQL正常關閉锨阿,這時候宵睦,MySQL會把內存的臟頁都flush到磁盤上,這樣下次MySQL啟動的時候墅诡,就可以直接從磁盤上讀數(shù)據(jù)壳嚎,啟動速度會很快。

image

那我們怎么做才能把握flush的時機呢末早?

Innodb刷臟頁控制策略烟馅,我們每個電腦主機的io能力是不一樣的,你要正確地告訴InnoDB所在主機的IO能力然磷,這樣InnoDB才能知道需要全力刷臟頁的時候郑趁,可以刷多快。

這就要用到innodb_io_capacity這個參數(shù)了姿搜,它會告訴InnoDB你的磁盤能力寡润,這個值建議設置成磁盤的IOPS,磁盤的IOPS可以通過fio這個工具來測試舅柜。

正確地設置innodb_io_capacity參數(shù)梭纹,可以有效的解決這個問題。

這中間有個有意思的點业踢,刷臟頁的時候栗柒,旁邊如果也是臟頁,會一起刷掉的知举,并且如果周圍還有臟頁瞬沦,這個連帶責任制會一直蔓延,這種情況其實在機械硬盤時代比較好雇锡,一次IO就解決了所有問題逛钻,

image

但是現(xiàn)在都是固態(tài)硬盤了,innodb_flush_neighbors=0這個參數(shù)可以不產(chǎn)生連帶制锰提,在MySQL 8.0中曙痘,innodb_flush_neighbors參數(shù)的默認值已經(jīng)是0了芳悲。

資料參考:《MySQL實戰(zhàn)》、《高性能MySQL》边坤、《丁奇MySQL47講》

總結

在本文中我提到了以下知識點:

image

應該還不算全名扛,行鎖、表鎖茧痒、間隙鎖肮韧、同步場景等等都沒怎么提到,因為他們的場景比較復雜旺订,每種都可以單獨開一篇了弄企,丁奇的MySQL里面算是很全了,還有就是高性能MySQL大家可以展開看看区拳,要是懶也可以等我總結拘领。

每個點我也沒多仔細的講解,主要是篇幅原因樱调,其實每個點在MySQL相關書籍都是很多篇幅才介紹完的约素,我就做個總結,對具體的概念不了解可以用搜索引擎查詢相關概念本涕,不過我想我說得還算通俗易懂业汰。

image

本文敖丙也就肝了一個多星期吧伙窃,主要是知識點的梳理菩颖,因為我也忘記得差不多了,我又回頭看了一遍为障,然后總結了一下晦闰,還有之前的筆記還在,本文我還是不開贊賞鳍怨,大家覺得可以點個在看就好了呻右,么么。

我是敖丙鞋喇,一個在互聯(lián)網(wǎng)茍且偷生的程序猿声滥。

你知道的越多窒升,你不知道的越多宅楞,人才們的 【三連】 就是丙丙創(chuàng)作的最大動力,我們下期見榨惠!

注:如果本篇博客有任何錯誤和建議罐韩,歡迎人才們留言憾赁!


文章持續(xù)更新,可以微信搜索「 三太子敖丙 」第一時間閱讀散吵,回復【資料】有我準備的一線大廠面試資料和簡歷模板龙考,本文 GitHub https://github.com/JavaFamily 已經(jīng)收錄蟆肆,有大廠面試完整考點,歡迎Star晦款。

image
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末炎功,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子缓溅,更是在濱河造成了極大的恐慌亡问,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肛宋,死亡現(xiàn)場離奇詭異州藕,居然都是意外死亡,警方通過查閱死者的電腦和手機酝陈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門床玻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沉帮,你說我怎么就攤上這事锈死。” “怎么了穆壕?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵待牵,是天一觀的道長。 經(jīng)常有香客問我喇勋,道長缨该,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任川背,我火速辦了婚禮贰拿,結果婚禮上,老公的妹妹穿的比我還像新娘熄云。我一直安慰自己膨更,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布缴允。 她就那樣靜靜地躺著荚守,像睡著了一般。 火紅的嫁衣襯著肌膚如雪练般。 梳的紋絲不亂的頭發(fā)上矗漾,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音踢俄,去河邊找鬼缩功。 笑死,一個胖子當著我的面吹牛都办,可吹牛的內容都是我干的嫡锌。 我是一名探鬼主播虑稼,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼势木!你這毒婦竟也來了蛛倦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤啦桌,失蹤者是張志新(化名)和其女友劉穎溯壶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甫男,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡且改,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了板驳。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片又跛。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖若治,靈堂內的尸體忽然破棺而出慨蓝,到底是詐尸還是另有隱情,我是刑警寧澤端幼,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布礼烈,位于F島的核電站,受9級特大地震影響婆跑,放射性物質發(fā)生泄漏此熬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一洽蛀、第九天 我趴在偏房一處隱蔽的房頂上張望摹迷。 院中可真熱鬧疟赊,春花似錦郊供、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吉执,卻和暖如春疯淫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戳玫。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工熙掺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咕宿。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓币绩,卻偏偏與公主長得像蜡秽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缆镣,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354