當前位置:首頁 » 編程語言 » sql為什麼會回表
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql為什麼會回表

發布時間: 2022-10-19 21:01:03

① 阿里三面:Mysql回表的性能傷害有多大

無論單列索引 or 聯合索引,一個索引就對應一個獨立的B+索引樹,索引樹節點僅包含:

即使根據索引樹按條件找到所需數據,也僅是索引里的幾個欄位的值和主鍵值,萬一你搞個select *,那就還得其他欄位,就需回表,根據主鍵到聚簇索引里找,聚簇索引的葉節點是數據頁,找到數據頁才能把一行數據所有欄位值讀出來。

所以類似

得從聯合索引的索引樹里按序取出所有數據,接著對每條數據都走一個主鍵的聚簇索引查找,性能不高。

有時MySQL執行引擎可能認為,你要是類似

相當於得把聯合索引和聚簇索引,兩個索引的所有數據都掃描一遍,那還不如不走聯合索引,直接全表掃描得了,這樣就只需掃描一個主鍵索引。

但若形如:

那執行引擎就知道你先掃描聯合索引的索引樹,拿到10條數據,接著對10條數據在聚簇索引里查找10次即可,那就還是會走聯合索引。

覆蓋索引不是一種索引,只是一種基於索引查詢的方式,即針對類似

僅需聯合索引里的幾個欄位的值,那就只需掃描聯合索引的索引樹,無需回表找其它欄位,這種查詢方式就是覆蓋索引。

所以當你使用聯合索引時,注意是否可能會導致大量回表到聚簇索引,若回表聚簇索引的次數太多,可能就直接給你做成全表掃描而不走聯合索引了。

盡可能還是在SQL里指定你僅需要的欄位,而不要暴力select *,最好直接走覆蓋索引。

即使無可避免地要回表,你也盡可能用limit、 where限定一下回表的次數,就從聯合索引里篩選少數數據,再回表,這樣性能好一點。

② mysql 核心內容-上

1、SQL語句執行流程

MySQL大體上可分為Server層和存儲引擎層兩部分。

Server層:

連接器:TCP握手後伺服器來驗證登陸用戶身份,A用戶創建連接後,管理員對A用戶許可權修改了也不會影響到已經創建的鏈接許可權,必須重新登陸。

查詢緩存:查詢後的結果存儲位置,MySQL8.0版本以後已經取消,因為查詢緩存失效太頻繁,得不償失。

分析器:根據語法規則,判斷你輸入的這個SQL語句是否滿足MySQL語法。

優化器:多種執行策略可實現目標,系統自動選擇最優進行執行。

執行器:判斷是否有許可權,將最終任務提交到存儲引擎。

存儲引擎層

負責數據的存儲和提取。其架構模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認存儲引擎(經常用的也是這個)。

SQL執行順序

2、BinLog、RedoLog、UndoLog

BinLog

BinLog是記錄所有資料庫表結構變更(例如create、alter table)以及表數據修改(insert、update、delete)的二進制日誌,主從資料庫同步用到的都是BinLog文件。BinLog日誌文件有三種模式。

STATEMENT 模式

內容:binlog 記錄可能引起數據變更的 sql 語句

優勢:該模式下,因為沒有記錄實際的數據,所以日誌量很少 IO 都消耗很低,性能是最優的

劣勢:但有些操作並不是確定的,比如 uuid() 函數會隨機產生唯一標識,當依賴 binlog 回放時,該操作生成的數據與原數據必然是不同的,此時可能造成無法預料的後果。

ROW 模式

內容:在該模式下,binlog 會記錄每次操作的源數據與修改後的目標數據,StreamSets就要求該模式。

優勢:可以絕對精準的還原,從而保證了數據的安全與可靠,並且復制和數據恢復過程可以是並發進行的

劣勢:缺點在於 binlog 體積會非常大,同時,對於修改記錄多、欄位長度大的操作來說,記錄時性能消耗會很嚴重。閱讀的時候也需要特殊指令來進行讀取數據。

MIXED 模式

內容:是對上述STATEMENT 跟 ROW 兩種模式的混合使用。

細節:對於絕大部分操作,都是使用 STATEMENT 來進行 binlog 沒有記錄,只有以下操作使用 ROW 來實現:表的存儲引擎為 NDB,使用了uuid() 等不確定函數,使用了 insert delay 語句,使用了臨時表

主從同步流程:

1、主節點必須啟用二進制日誌,記錄任何修改了資料庫數據的事件。

2、從節點開啟一個線程(I/O Thread)把自己扮演成 mysql 的客戶端,通過 mysql 協議,請求主節點的二進制日誌文件中的事件 。

3、主節點啟動一個線程(mp Thread),檢查自己二進制日誌中的事件,跟對方請求的位置對比,如果不帶請求位置參數,則主節點就會從第一個日誌文件中的第一個事件一個一個發送給從節點。

4、從節點接收到主節點發送過來的數據把它放置到中繼日誌(Relay log)文件中。並記錄該次請求到主節點的具體哪一個二進制日誌文件內部的哪一個位置(主節點中的二進制文件會有多個)。

5、從節點啟動另外一個線程(sql Thread ),把 Relay log 中的事件讀取出來,並在本地再執行一次。

mysql默認的復制方式是非同步的,並且復制的時候是有並行復制能力的。主庫把日誌發送給從庫後不管了,這樣會產生一個問題就是假設主庫掛了,從庫處理失敗了,這時候從庫升為主庫後,日誌就丟失了。由此產生兩個概念。

全同步復制

主庫寫入binlog後強制同步日誌到從庫,所有的從庫都執行完成後才返回給客戶端,但是很顯然這個方式的話性能會受到嚴重影響。

半同步復制

半同步復制的邏輯是這樣,從庫寫入日誌成功後返回ACK確認給主庫,主庫收到至少一個從庫的確認就認為寫操作完成。

還可以延伸到由於主從配置不一樣、主庫大事務、從庫壓力過大、網路震盪等造成主備延遲,如何避免這個問題?主備切換的時候用可靠性優先原則還是可用性優先原則?如何判斷主庫Crash了?互為主備的情況下如何避免主備循環復制?被刪庫跑路了如何正確恢復?( o )… 感覺越來越扯到DBA的活兒上去了。

RedoLog

可以先通過下面demo理解:

飯點記賬可以把賬單寫在賬本上也可以寫在粉板上。有人賒賬或者還賬的話,一般有兩種做法:

1、直接把賬本翻出來,把這次賒的賬加上去或者扣除掉。

2、先在粉板上記下這次的賬,等打烊以後再把賬本翻出來核算。

生意忙時選後者,因為前者太麻煩了。得在密密麻麻的記錄中找到這個人的賒賬總額信息,找到之後再拿出算盤計算,最後再將結果寫回到賬本上。

同樣在MySQL中如果每一次的更新操作都需要寫進磁碟,然後磁碟也要找到對應的那條記錄,然後再更新,整個過程IO成本、查找成本都很高。而粉板和賬本配合的整個過程就是MySQL用到的是Write-Ahead Logging 技術,它的關鍵點就是先寫日誌,再寫磁碟。此時賬本 = BinLog,粉板 = RedoLog。

1、 記錄更新時,InnoDB引擎就會先把記錄寫到RedoLog(粉板)裡面,並更新內存。同時,InnoDB引擎會在空閑時將這個操作記錄更新到磁碟裡面。

2、 如果更新太多RedoLog處理不了的時候,需先將RedoLog部分數據寫到磁碟,然後擦除RedoLog部分數據。RedoLog類似轉盤。

RedoLog有write pos 跟checkpoint

write pos :是當前記錄的位置,一邊寫一邊後移,寫到第3號文件末尾後就回到0號文件開頭。

check point:是當前要擦除的位置,也是往後推移並且循環的,擦除記錄前要把記錄更新到數據文件。

write pos和check point之間的是粉板上還空著的部分,可以用來記錄新的操作。如果write pos追上checkpoint,表示粉板滿了,這時候不能再執行新的更新,得停下來先擦掉一些記錄,把checkpoint推進一下。

有了redo log,InnoDB就可以保證即使資料庫發生異常重啟,之前提交的記錄都不會丟失,這個能力稱為crash-safe。 redolog兩階段提交:為了讓binlog跟redolog兩份日誌之間的邏輯一致。提交流程大致如下:

1 prepare階段 --> 2 寫binlog --> 3 commit

當在2之前崩潰時,重啟恢復後發現沒有commit,回滾。備份恢復:沒有binlog 。一致

當在3之前崩潰時,重啟恢復發現雖沒有commit,但滿足prepare和binlog完整,所以重啟後會自動commit。備份:有binlog. 一致

binlog跟redolog區別:

redo log是InnoDB引擎特有的;binlog是MySQL的Server層實現的,所有引擎都可以使用。

redo log是物理日誌,記錄的是在某個數據頁上做了什麼修改;binlog是邏輯日誌,記錄的是這個語句的原始邏輯,比如給ID=2這一行的c欄位加1。

redo log是循環寫的,空間固定會用完;binlog是可以追加寫入的。追加寫是指binlog文件寫到一定大小後會切換到下一個,並不會覆蓋以前的日誌。

UndoLog

UndoLog 一般是邏輯日誌,主要分為兩種:

insert undo log

代表事務在insert新記錄時產生的undo log, 只在事務回滾時需要,並且在事務提交後可以被立即丟棄

update undo log

事務在進行update或delete時產生的undo log; 不僅在事務回滾時需要,在快照讀時也需要;所以不能隨便刪除,只有在快速讀或事務回滾不涉及該日誌時,對應的日誌才會被purge線程統一清除

3、MySQL中的索引

索引的常見模型有哈希表、有序數組和搜索樹。

哈希表:一種以KV存儲數據的結構,只適合等值查詢,不適合范圍查詢。

有序數組:只適用於靜態存儲引擎,涉及到插入的時候比較麻煩。可以參考Java中的ArrayList。

搜索樹:按照數據結構中的二叉樹來存儲數據,不過此時是N叉樹(B+樹)。廣泛應用在存儲引擎層中。

B+樹比B樹優勢在於:

B+ 樹非葉子節點存儲的只是索引,可以存儲的更多。B+樹比B樹更加矮胖,IO次數更少。

B+ 樹葉子節點前後管理,更加方便范圍查詢。同時結果都在葉子節點,查詢效率穩定。

B+樹中更有利於對數據掃描,可以避免B樹的回溯掃描。

索引的優點:

1、唯一索引可以保證每一行數據的唯一性

2、提高查詢速度

3、加速表與表的連接

4、顯著的減少查詢中分組和排序的時間

5、通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。

索引的缺點:

1、創建跟維護都需要耗時

2、創建索引時,需要對表加鎖,在鎖表的同時,可能會影響到其他的數據操作

3、 索引需要磁碟的空間進行存儲,磁碟佔用也很快。

4、當對表中的數據進行CRUD的時,也會觸發索引的維護,而維護索引需要時間,可能會降低數據操作性能

索引設計的原則不應該:

1、索引不是越多越好。索引太多,維護索引需要時間跟空間。

2、 頻繁更新的數據,不宜建索引。

3、數據量小的表沒必要建立索引。

應該:

1、重復率小的列建議生成索引。因為重復數據少,索引樹查詢更有效率,等價基數越大越好。

2、數據具有唯一性,建議生成唯一性索引。在資料庫的層面,保證數據正確性

3、頻繁group by、order by的列建議生成索引。可以大幅提高分組和排序效率

4、經常用於查詢條件的欄位建議生成索引。通過索引查詢,速度更快

索引失效的場景

1、模糊搜索:左模糊或全模糊都會導致索引失效,比如'%a'和'%a%'。但是右模糊是可以利用索引的,比如'a%' 。

2、隱式類型轉換:比如select * from t where name = xxx , name是字元串類型,但是沒有加引號,所以是由MySQL隱式轉換的,所以會讓索引失效 3、當語句中帶有or的時候:比如select * from t where name=『sw』 or age=14

4、不符合聯合索引的最左前綴匹配:(A,B,C)的聯合索引,你只where了C或B或只有B,C

關於索引的知識點:

主鍵索引:主鍵索引的葉子節點存的是整行數據信息。在InnoDB里,主鍵索引也被稱為聚簇索引(clustered index)。主鍵自增是無法保證完全自增的哦,遇到唯一鍵沖突、事務回滾等都可能導致不連續。

唯一索引:以唯一列生成的索引,該列不允許有重復值,但允許有空值(NULL)

普通索引跟唯一索引查詢性能:InnoDB的數據是按數據頁為單位來讀寫的,默認每頁16KB,因此這兩種索引查詢數據性能差別微乎其微。

change buffer:普通索引用在更新過程的加速,更新的欄位如果在緩存中,如果是普通索引則直接更新即可。如果是唯一索引需要將所有數據讀入內存來確保不違背唯一性,所以盡量用普通索引。

非主鍵索引:非主鍵索引的葉子節點內容是主鍵的值。在InnoDB里,非主鍵索引也被稱為二級索引(secondary index)

回表:先通過資料庫索引掃描出數據所在的行,再通過行主鍵id取出索引中未提供的數據,即基於非主鍵索引的查詢需要多掃描一棵索引樹。

覆蓋索引:如果一個索引包含(或者說覆蓋)所有需要查詢的欄位的值,我們就稱之為覆蓋索引。

聯合索引:相對單列索引,組合索引是用多個列組合構建的索引,一次性最多聯合16個。

最左前綴原則:對多個欄位同時建立的組合索引(有順序,ABC,ACB是完全不同的兩種聯合索引) 以聯合索引(a,b,c)為例,建立這樣的索引相當於建立了索引a、ab、abc三個索引。另外組合索引實際還是一個索引,並非真的創建了多個索引,只是產生的效果等價於產生多個索引。

索引下推:MySQL 5.6引入了索引下推優化,可以在索引遍歷過程中,對索引中包含的欄位先做判斷,過濾掉不符合條件的記錄,減少回表字數。

索引維護:B+樹為了維護索引有序性涉及到頁分裂跟頁合並。增刪數據時需考慮頁空間利用率。

自增主鍵:一般會建立與業務無關的自增主鍵,不會觸發葉子節點分裂。

延遲關聯:通過使用覆蓋索引查詢返回需要的主鍵,再根據主鍵關聯原表獲得需要的數據。

InnoDB存儲: * .frm文件是一份定義文件,也就是定義資料庫表是一張怎麼樣的表。*.ibd文件則是該表的索引,數據存儲文件,既該表的所有索引樹,所有行記錄數據都存儲在該文件中。

MyISAM存儲:* .frm文件是一份定義文件,也就是定義資料庫表是一張怎麼樣的表。* .MYD文件是MyISAM存儲引擎表的所有行數據的文件。* .MYI文件存放的是MyISAM存儲引擎表的索引相關數據的文件。MyISAM引擎下,表數據和表索引數據是分開存儲的。

MyISAM查詢:在MyISAM下,主鍵索引和輔助鍵索引都屬於非聚簇索引。查詢不管是走主鍵索引,還是非主鍵索引,在葉子結點得到的都是目的數據的地址,還需要通過該地址,才能在數據文件中找到目的數據。

PS:InnoDB支持聚簇索引,MyISAM不支持聚簇索引

4、SQL事務隔離級別

ACID的四個特性

原子性(Atomicity):把多個操作放到一個事務中,保證這些操作要麼都成功,要麼都不成功

一致性(Consistency):理解成一串對數據進行操作的程序執行下來,不會對數據產生不好的影響,比如憑空產生,或消失

隔離性(Isolation,又稱獨立性):隔離性的意思就是多個事務之間互相不幹擾,即使是並發事務的情況下,他們只是兩個並發執行沒有交集,互不影響的東西;當然實現中,也不一定需要這么完整隔離性,即不一定需要這么的互不幹擾,有時候還是允許有部分干擾的。所以MySQL可以支持4種事務隔離性

持久性(Durability):當某個操作操作完畢了,那麼結果就是這樣了,並且這個操作會持久化到日誌記錄中

PS:ACID中C與CAP定理中C的區別

ACID的C著重強調單資料庫事務操作時,要保證數據的完整和正確性,數據不會憑空消失跟增加。CAP 理論中的C指的是對一個數據多個備份的讀寫一致性

事務操作可能會出現的數據問題

1、臟讀(dirty read):B事務更改數據還未提交,A事務已經看到並且用了。B事務如果回滾,則A事務做錯了

2、 不可重復讀(non-repeatable read):不可重復讀的重點是修改: 同樣的條件, 你讀取過的數據, 再次讀取出來發現值不一樣了,只需要鎖住滿足條件的記錄

3、 幻讀(phantom read):事務A先修改了某個表的所有紀錄的狀態欄位為已處理,未提交;事務B也在此時新增了一條未處理的記錄,並提交了;事務A隨後查詢記錄,卻發現有一條記錄是未處理的造成幻讀現象,幻讀僅專指新插入的行。幻讀會造成語義上的問題跟數據一致性問題。

4、 在可重復讀RR隔離級別下,普通查詢是快照讀,是不會看到別的事務插入的數據的。因此,幻讀在當前讀下才會出現。要用間隙鎖解決此問題。

在說隔離級別之前,你首先要知道,你隔離得越嚴實,效率就會越低。因此很多時候,我們都要在二者之間尋找一個平衡點。SQL標準的事務隔離級別由低到高如下: 上圖從上到下的模式會導致系統的並行性能依次降低,安全性依次提高。

讀未提交:別人改數據的事務尚未提交,我在我的事務中也能讀到。

讀已提交(Oracle默認):別人改數據的事務已經提交,我在我的事務中才能讀到。

可重復讀(MySQL默認):別人改數據的事務已經提交,我在我的事務中也不去讀,以此保證重復讀一致性。

串列:我的事務尚未提交,別人就別想改數據。

標准跟實現:上面都是關於事務的標准,但是每一種資料庫都有不同的實現,比如MySQL InnDB 默認為RR級別,但是不會出現幻讀。因為當事務A更新了所有記錄的某個欄位,此時事務A會獲得對這個表的表鎖,因為事務A還沒有提交,所以事務A獲得的鎖沒有釋放,此時事務B在該表插入新記錄,會因為無法獲得該表的鎖,則導致插入操作被阻塞。只有事務A提交了事務後,釋放了鎖,事務B才能進行接下去的操作。所以可以說 MySQL的RR級別的隔離是已經實現解決了臟讀,不可重復讀和幻讀的。

5、MySQL中的鎖

無論是Java的並發編程還是資料庫的並發操作都會涉及到鎖,研發人員引入了悲觀鎖跟樂觀鎖這樣一種鎖的設計思想。

悲觀鎖:

優點:適合在寫多讀少的並發環境中使用,雖然無法維持非常高的性能,但是在樂觀鎖無法提更好的性能前提下,可以做到數據的安全性

缺點:加鎖會增加系統開銷,雖然能保證數據的安全,但數據處理吞吐量低,不適合在讀書寫少的場合下使用

樂觀鎖:

優點:在讀多寫少的並發場景下,可以避免資料庫加鎖的開銷,提高DAO層的響應性能,很多情況下ORM工具都有帶有樂觀鎖的實現,所以這些方法不一定需要我們人為的去實現。

缺點:在寫多讀少的並發場景下,即在寫操作競爭激烈的情況下,會導致CAS多次重試,沖突頻率過高,導致開銷比悲觀鎖更高。

實現:資料庫層面的樂觀鎖其實跟CAS思想類似, 通數據版本號或者時間戳也可以實現。

資料庫並發場景主要有三種:

讀-讀:不存在任何問題,也不需要並發控制

讀-寫:有隔離性問題,可能遇到臟讀,幻讀,不可重復讀

寫-寫:可能存更新丟失問題,比如第一類更新丟失,第二類更新丟失

兩類更新丟失問題:

第一類更新丟失:事務A的事務回滾覆蓋了事務B已提交的結果 第二類更新丟失:事務A的提交覆蓋了事務B已提交的結果

為了合理貫徹落實鎖的思想,MySQL中引入了雜七雜八的各種鎖:

鎖分類

MySQL支持三種層級的鎖定,分別為

表級鎖定

MySQL中鎖定粒度最大的一種鎖,最常使用的MYISAM與INNODB都支持表級鎖定。

頁級鎖定

是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖,表級鎖速度快,但沖突多,行級沖突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。

行級鎖定

Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的沖突。其加鎖粒度最小,但加鎖的開銷也最大行級鎖不一定比表級鎖要好:鎖的粒度越細,代價越高,相比表級鎖在表的頭部直接加鎖,行級鎖還要掃描找到對應的行對其上鎖,這樣的代價其實是比較高的,所以表鎖和行鎖各有所長。

MyISAM中的鎖

雖然MySQL支持表,頁,行三級鎖定,但MyISAM存儲引擎只支持表鎖。所以MyISAM的加鎖相對比較開銷低,但數據操作的並發性能相對就不高。但如果寫操作都是尾插入,那還是可以支持一定程度的讀寫並發

從MyISAM所支持的鎖中也可以看出,MyISAM是一個支持讀讀並發,但不支持通用讀寫並發,寫寫並發的資料庫引擎,所以它更適合用於讀多寫少的應用場合,一般工程中也用的較少。

InnoDB中的鎖

該模式下支持的鎖實在是太多了,具體如下:

共享鎖和排他鎖 (Shared and Exclusive Locks)

意向鎖(Intention Locks)

記錄鎖(Record Locks)

間隙鎖(Gap Locks)

臨鍵鎖 (Next-Key Locks)

插入意向鎖(Insert Intention Locks)

主鍵自增鎖 (AUTO-INC Locks)

空間索引斷言鎖(Predicate Locks for Spatial Indexes)

舉個栗子,比如行鎖里的共享鎖跟排它鎖:lock in share modle 共享讀鎖:

為了確保自己查到的數據沒有被其他的事務正在修改,也就是說確保查到的數據是最新的數據,並且不允許其他人來修改數據。但是自己不一定能夠修改數據,因為有可能其他的事務也對這些數據使用了 in share mode 的方式上了S 鎖。如果不及時的commit 或者rollback 也可能會造成大量的事務等待。

for update排它寫鎖:

為了讓自己查到的數據確保是最新數據,並且查到後的數據只允許自己來修改的時候,需要用到for update。相當於一個 update 語句。在業務繁忙的情況下,如果事務沒有及時的commit或者rollback 可能會造成其他事務長時間的等待,從而影響資料庫的並發使用效率。

Gap Lock間隙鎖:

1、行鎖只能鎖住行,如果在記錄之間的間隙插入數據就無法解決了,因此MySQL引入了間隙鎖(Gap Lock)。間隙鎖是左右開區間。間隙鎖之間不會沖突。

2、間隙鎖和行鎖合稱NextKeyLock,每個NextKeyLock是前開後閉區間。

間隙鎖加鎖原則(學完忘那種):

1、加鎖的基本單位是 NextKeyLock,是前開後閉區間。

2、查找過程中訪問到的對象才會加鎖。

3、索引上的等值查詢,給唯一索引加鎖的時候,NextKeyLock退化為行鎖。

4、索引上的等值查詢,向右遍歷時且最後一個值不滿足等值條件的時候,NextKeyLock退化為間隙鎖。

5、唯一索引上的范圍查詢會訪問到不滿足條件的第一個值為止。

③ SQL SERVER 資料庫 數據為什麼自動還原了

需要手動進行。
如果是只還原一張表,建議從備份文件中還原時 選擇一張表 ,而不是整個庫都還原;
建議新建一個存儲過程和一張臨時表,當源表發生新增,刪除,修改時,將數據備份到臨時表中,還原數據時可以從臨時表進行。

④ SQL SERVER 資料庫 數據為什麼自動還原了

備份資料庫
1,打開SQL企業管理器,在控制台根目錄中依次點開的Microsoft SQL Server頁2,SQL Server組 - >雙擊打開你的伺服器 - >雙擊打開資料庫目錄頁3,選擇你的資料庫名稱(如論壇資料庫論壇) - >然後在上面的菜單工具 - >選擇備份資料庫
4,備份選項選擇完全備份,如果備份的目的原來還有的選擇的名稱指向的路徑和名稱刪除,然後添加,如果原來沒有路徑和名稱直接選擇添加,接著指定路徑和文件名,然後單擊確定後,在指定的備份窗口返回,然後單擊確定備份
二,還原資料庫
1,打開SQL企業管理器,在控制台根目錄中依次點開的Microsoft SQL Server頁2,SQL Server組 - >雙擊打開你的伺服器 - 新建資料庫>點圖標欄的圖標,把自己的新資料庫的名稱頁3,點擊新建好的資料庫名稱 - >然後上面的菜單工具 - >選擇恢復資料庫頁4,在彈出的窗口中的還原選項中選擇從設備 - >點選擇設備 - >點添加 - >然後選擇你的備份文件的名稱 - >確定加點後返回,則此欄應顯示在設備您只需選擇資料庫備份文件名,備份號默認為1(如果你也犯了同樣的文件多備份,可以點擊旁邊的備份編號,以查看內容,點擊確定選擇後的復選框最新的備份) - >然後單擊選項按鈕旁邊的普通頁5的頂部,選擇強制降低,在出現的窗口中現有的資料庫,然後選擇恢復完成狀態,以便可以繼續運行資料庫的事務日誌,但其他選項無法恢復。減少在資料庫文件是按照您的SQL安裝設置窗口的中間(可以指定自己的目錄),邏輯文件名不需要更改,移動物理文件名你要根據恢復的機器上做一旦發生變動,如安裝在D SQL資料庫:\ Program Files文件\的Microsoft SQL Server \ MSSQL \ Data資料,然後根據你的目錄更改相關的變化中恢復,以及文件的名字到當前的資料庫最好的名字(比如原來是zw0001.mdf,現在的資料庫是zw0002,它改變了zw0002.mdf),日誌和數據文件應該以這樣的方式相關的變化來完成(文件名是日誌的.LDF結束),在這里你可以自由設置恢復目錄,前提是該目錄必須存在(例如,您可以指定D:\ SQLDATA \ zw0002.mdf或D:\ SQLDATA \ zw0002.ldf),否則恢復將是錯誤
6,後完成點擊下面的確定恢復,然後會出現一個進度條,進度迅速恢復,恢復完成後系統會自動提示成功,如中間提示錯誤相關的錯誤內容請記下並要求SQL操作人員比較熟悉,一般誤差小於一個目錄或文件名錯誤或重復的文件名錯誤或者空間不足,或者在錯誤的資料庫正在使用,正在使用錯誤的資料庫,你可以嘗試關閉所有窗口僅此而已並重新對SQL恢復操作,如果提示錯誤被用於恢復,可以停止SQL服務,然後重新啟動看看,因為按照這些一般其他錯誤錯誤內容可以做出相應的改變

⑤ ms sql 2000 執行update後,數據為什麼會自動還原

額,正常的,因為你程序異常了,所以數據回滾了,這個是資料庫的正常機制。

⑥ 淺聊 MySQL索引覆蓋

盡量使用覆蓋索引,減少select *。 那麼什麼是覆蓋索引呢? 覆蓋索引是指 查詢使用了索引,並 且需要返回的列,在該索引中已經全部能夠找到 。

現在有一張用戶表tb_user;

索引情況:

接下來,我們來看一組SQL的執行計劃,看看執行計劃的差別,然後再來具體做一個解析。

Using where; Using Index:查找使用了索引,但是需要的數據都在索引列中能找到,所以不需 要回表查詢數據

Using index condition:查找使用了索引,但是需要回表查詢數據

因為,在tb_user表中有一個聯合索引 idx_user_pro_age_sta,該索引關聯了三個欄位 profession、age、status,而這個索引也是一個二級索引,所以葉子節點下面掛的是這一行的主 鍵id。 所以當我們查詢返回的數據在 id、profession、age、status 之中,則直接走二級索引 直接返回數據了。 如果超出這個范圍,就需要拿到主鍵id,再去掃描聚集索引,再獲取額外的數據了,這個過程就是回表。 而我們如果一直使用select * 查詢返回所有欄位值,很容易就會造成回表 查詢(除非是根據主鍵查詢,此時只會掃描聚集索引)。

為了大家更清楚的理解,什麼是覆蓋索引,什麼是回表查詢,我們一起再來看下面的這組SQL的執行過 程。

id是主鍵,是一個聚集索引。 name欄位建立了普通索引,是一個二級索引(輔助索引)。

B. 執行SQL : select * from tb_user where id = 2;

根據id查詢,直接走聚集索引查詢,一次索引掃描,直接返回數據,性能高。

C. 執行SQL:selet id,name from tb_user where name = 'Arm';

雖然是根據name欄位查詢,查詢二級索引,但是由於查詢返回在欄位為 id,name,在name的二級索 引中,這兩個值都是可以直接獲取到的,因為覆蓋索引,所以不需要回表查詢,性能高。

D. 執行SQL:selet id,name,gender from tb_user where name = 'Arm';

由於在name的二級索引中,不包含gender,所以,需要兩次索引掃描,也就是需要回表查詢,性能相 對較差一點。

⑦ mysql索引問題

1.首選資料庫都會有自動優化查詢計劃的能力,在語句一中,明顯對seq進行了排序,而is_need_udate用in進行范圍查詢,使用index2,開銷就會小很多,但是語句二中is_need_update沒有這個了,所以才會使用index1.
2.所以建立的原則
2.1根據對應表查詢頻率最高的屬性建立索引
2.2為經常需要排序,分組的欄位建立索引
2.3盡量使用數據量少的索引
建議詳細的使用方法看看書吧,資料庫的優化是一門大學問,值得好好研究的

⑧ 堆表、回表、索引覆蓋、主鍵索引、聚集索引等一些知識點

mysql 一定是索引組織表,且主鍵索引一定也是聚集索引。 所以 mysql 二級索引的葉子節點一定存放的是主鍵的值。
受mysql 影響,我也一度以為sql server 二級索引葉子節點也是存儲的主鍵索引。但實際不一定是。
下面通過一個例子來慢慢探究一下

先構造一個測試數據,並創建一個二級索引

然後,我們寫一個查詢,強制走二級索引

從實際計劃中可以看到。因為二級索引 ix_testIndex 沒有 我需要的所有列,所以需要回表拿更多數據,但從圖中看到,這次回表走的是heap堆表回表拿數據.

我們再創建一個主鍵索引,將這個主鍵索引創建為非聚集的

看一下現在的索引情況

然後再看上一個語句

再看執行計劃

回表還是走的堆表

我們繼續,創建一個聚集索引

看一下現在的索引

繼續執行

從執行計劃中看到。這次索引沒有回表。在二級索引上拿到了所有需要的數據,完成了索引覆蓋,那就可以證明二級索引ix_testIndex 葉子節點存儲的就是聚集索引id列的值。

再改一下語句 強制走主鍵索引

從執行計劃中可以看出,由於主鍵索引只有 id列,聚集也只有id列,所以主鍵索引拿不到tname列 需要回表, 這次回表就是回的聚集索引了。

所以sql server與mysql 還是有很大我區別。

1、sql server 主鍵索引只是一個約束,只有當它是聚集索引的時候,二級索引葉子節點才是主鍵的值
2、沒有聚集索引的時候, 就是堆表,而不是索引組織表
3、有聚集索引的時候,就變成了索引組織表
4、二級索引葉子節點,存儲的是聚集索引列的值。

⑨ 怎麼解決sql低效回表問題

很簡單,改演算法就行了。
1.先從單一SQL改成多步式聯動的散SQL查詢集群。並且單表多條件為契機修改查詢條件與數據返回的欄位記錄到內存上。
保證每次查詢即需要,每次緩存不重復原則。
2.再把原伺服器消耗的CPU性能往客戶端轉移,變成客戶端的帶寬+瀏覽器運算轉嫁。
畢竟現在客戶電腦資源都很高,計算在用戶後台比集中在資料庫利用CPU計算要劃算得多。
3.最後通過非同步異表方式進行無讀書批量性跟資料庫發起請求。這個操作也是為了方便日後換NOSQL資料庫後不需要改演算法。
批量非同步操作會最大限度讓資料庫的緩存命中率提高,IO壓力只需要頭一次,後面的基本都是緩存的事了。
4.通過多個數據集與運算方式通過前端計算後展示給用戶
這個不用解析了,資料庫最終關系掛靠在前端進行,就算被反編譯因為沒有具體SQL根本看不出數結構,代碼安全性也提高了。
以上方法優化後十億級數據量每秒並非400+的查詢,到前台用戶顯示也就1秒內而已。

⑩ MySQL深分頁調優實戰

商品評論系統數據量為十億量級,因此對評論資料庫做分庫分表,單表的評論數據在百萬級別。

每個商品的所有評論都是放在一個庫的一張表裡,確保作為用戶在分頁查詢一個商品的評論時,一般都是直接從一個庫的一張表裡執行分頁查詢語句即可。

熱門商品銷量多達上百萬,商品評論可能多達幾十萬條。有些用戶就喜歡看商品評論,他就喜歡不停對某個熱門商品評論不斷進行分頁,一頁一頁翻,有時候還會用上分頁跳轉功能,就是直接輸入自己要跳到第幾頁。

這就涉及針對一個商品幾十萬評論的深分頁問題。

簡化後的對評論表進行分頁查詢的SQL:

比如用戶選擇了查看某個商品的評論,因此必須限定 Proct_id ,同時還選了只看好評,所以 is_good_commit 也要限定,

接著看第5001頁評論,則limit的offset=(5001 - 1) * 20,20是每頁的數量, 此時起始offset就是100000,所以limit後100000,20。

評論表最核心的索引 index_proct_id ,所以正常肯定走這索引:

該過程有幾十萬次回表查詢,還有十多萬條數據的磁碟文件排序,所以要跑個1~2s。如何優化呢?

但本案例不是這樣,因為

這倆條件不是一個聯合索引,所以會出現大量回表,耗時嚴重。

因此對該案例,一般採取如下方式改造分頁查詢語句:

該SQL的執行計劃就會徹底改變其執行方式。

通常先執行括弧里的子查詢,子查詢反而會使用PRIMARY聚簇索引,按聚簇索引id值的倒序方向進行掃描,掃描過程中就把符合

的數據篩選出來。

比如這里篩選出10w條數據,並不需要把符合條件的數據都找到,因為limit 100000,20,理論上,只要有100000+20條符合條件的數據,且按id有序的,此時就能執行根據limit 100000,20提取到5001頁的這20條數據。

接著你會看到執行計劃里會針對這個子查詢的結果集,一個臨時表,進行全表掃描,拿到20條數據,再對20條數據遍歷,每條數據都按id去聚簇索引查找一下完整數據。

所以本案例,反而是優化成這種方式來執行分頁,更合適,他只有一個掃描【聚簇索引】篩選符合你分頁所有數據的成本:

然後再做一頁20條數據的20次回表查詢即可。當時做了該分頁優化後,發現分頁語句一下子執行時間降低到了幾百ms,達到優化目的。

SQL調優沒有銀彈:

不同場景,要具體情況具體分析,到底慢在哪兒,再針對性優化。