1. 程式人生 > >資料庫-面試題-MySQL資料庫的優化方法

資料庫-面試題-MySQL資料庫的優化方法

1、選取最適用的欄位屬性

MySQL可以很好的支援大資料量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在建立表的時候,為了獲得更好的效能,我們可以將表中欄位的寬度設得儘可能小。

例如,在定義郵政編碼這個欄位時,如果將其設定為CHAR(255),顯然給資料庫增加了不必要的空間,甚至使用VARCHAR這種型別也是多餘的,因為CHAR(6)就可以很好的完成任務了。同樣的,如果可以的話,我們應該使用MEDIUMINT而不是BIGIN來定義整型欄位。

另外一個提高效率的方法是在可能的情況下,應該儘量把欄位設定為NOTNULL,這樣在將來執行查詢的時候,資料庫不用去比較NULL值。
對於某些文字欄位,例如“省份”或者“性別”,我們可以將它們定義為ENUM型別。因為在MySQL中,ENUM型別被當作數值型資料來處理,而數值型資料被處理起來的速度要比文字型別快得多。這樣,我們又可以提高資料庫的效能。

2、使用連線(JOIN)來代替子查詢(Sub-Queries)

MySQL從4.1開始支援SQL的子查詢。這個技術可以使用SELECT語句來建立一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。例如,我們要將客戶基本資訊表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售資訊表中將所有發出訂單的客戶ID取出來,然後將結果傳遞給主查詢,如下所示:

DELETEFROMcustomerinfo

WHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)

使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作,同時也可以避免事務或者表鎖死,並且寫起來也很容易。但是,有些情況下,子查詢可以被更有效率的連線(JOIN)..替代。例如,假設我們要將所有沒有訂單記錄的使用者取出來,可以用下面這個查詢完成:

SELECT*FROMcustomerinfo

WHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)

如果使用連線(JOIN)..來完成這個查詢工作,速度將會快很多。尤其是當salesinfo表中對CustomerID建有索引的話,效能將會更好,查詢如下:

SELECT*FROMcustomerinfo

LEFTJOINsalesinfoONcustomerinfo.CustomerID=salesinfo.CustomerID

WHEREsalesinfo.CustomerIDISNULL

連線(JOIN)..之所以更有效率一些,是因為MySQL不需要在記憶體中建立臨時表來完成這個邏輯上的需要兩個步驟的查詢工作。

3、使用聯合(UNION)來代替手動建立的臨時表

MySQL從4.0的版本開始支援union查詢,它可以把需要使用臨時表的兩條或更多的select查詢合併的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。使用union來建立查詢的時候,我們只需要用UNION作為關鍵字把多個select語句連線起來就可以了,要注意的是所有select語句中的欄位數目要想同。下面的例子就演示了一個使用UNION的查詢。

SELECTName,PhoneFROMclientUNION

SELECTName,BirthDateFROMauthorUNION

SELECTName,SupplierFROMproduct

4、事務

儘管我們可以使用子查詢(Sub-Queries)、連線(JOIN)和聯合(UNION)來建立各種各樣的查詢,但不是所有的資料庫操作都可以只用一條或少數幾條SQL語句就可以完成的。更多的時候是需要用到一系列的語句來完成某種工作。但是在這種情況下,當這個語句塊中的某一條語句執行出錯的時候,整個語句塊的操作就會變得不確定起來。設想一下,要把某個資料同時插入兩個相關聯的表中,可能會出現這樣的情況:第一個表中成功更新後,資料庫突然出現意外狀況,造成第二個表中的操作沒有完成,這樣,就會造成資料的不完整,甚至會破壞資料庫中的資料。要避免這種情況,就應該使用事務,它的作用是:要麼語句塊中每條語句都操作成功,要麼都失敗。換句話說,就是可以保持資料庫中資料的一致性和完整性。事物以BEGIN關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操作失敗,那麼,ROLLBACK命令就可以把資料庫恢復到BEGIN開始之前的狀態。

BEGIN; INSERTINTOsalesinfoSETCustomerID=14;UPDATEinventorySETQuantity=11WHEREitem='book';COMMIT;

事務的另一個重要作用是當多個使用者同時使用相同的資料來源時,它可以利用鎖定資料庫的方法來為使用者提供一種安全的訪問方式,這樣可以保證使用者的操作不被其它的使用者所幹擾。

5、鎖定表

儘管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨佔性,有時會影響資料庫的效能,尤其是在很大的應用系統中。由於在事務執行的過程中,資料庫將會被鎖定,因此其它的使用者請求只能暫時等待直到該事務結束。如果一個數據庫系統只有少數幾個使用者來使用,事務造成的影響不會成為一個太大的問題;但假設有成千上萬的使用者同時訪問一個數據庫系統,例如訪問一個電子商務網站,就會產生比較嚴重的響應延遲。

其實,有些情況下我們可以通過鎖定表的方法來獲得更好的效能。下面的例子就用鎖定表的方法來完成前面一個例子中事務的功能。

LOCKTABLEinventoryWRITESELECTQuantityFROMinventoryWHEREItem='book';

...

UPDATEinventorySETQuantity=11WHEREItem='book';UNLOCKTABLES

這裡,我們用一個select語句取出初始資料,通過一些計算,用update語句將新值更新到表中。包含有WRITE關鍵字的LOCKTABLE語句可以保證在UNLOCKTABLES命令被執行之前,不會有其它的訪問來對inventory進行插入、更新或者刪除的操作。

6、使用外來鍵

鎖定表的方法可以維護資料的完整性,但是它卻不能保證資料的關聯性。這個時候我們就可以使用外來鍵。

例如,外來鍵可以保證每一條銷售記錄都指向某一個存在的客戶。在這裡,外來鍵可以把customerinfo表中的CustomerID對映到salesinfo表中CustomerID,任何一條沒有合法CustomerID的記錄都不會被更新或插入到salesinfo中。

CREATETABLEcustomerinfo( CustomerIDINTNOTNULL,PRIMARYKEY(CustomerID))TYPE=INNODB;

CREATETABLEsalesinfo( SalesIDINTNOTNULL,CustomerIDINTNOTNULL,

PRIMARYKEY(CustomerID,SalesID),

FOREIGNKEY(CustomerID)REFERENCEScustomerinfo(CustomerID)ONDELETECASCADE)TYPE=INNODB;

注意例子中的引數“ONDELETECASCADE”。該引數保證當customerinfo表中的一條客戶記錄被刪除的時候,salesinfo表中所有與該客戶相關的記錄也會被自動刪除。如果要在MySQL中使用外來鍵,一定要記住在建立表的時候將表的型別定義為事務安全表InnoDB型別。該型別不是MySQL表的預設型別。定義的方法是在CREATETABLE語句中加上TYPE=INNODB。如例中所示。

7、使用索引

索引是提高資料庫效能的常用方法,它可以令資料庫伺服器以比沒有索引快得多的速度檢索特定的行,尤其是在查詢語句當中包含有MAX(),MIN()和ORDERBY這些命令的時候,效能提高更為明顯。

那該對哪些欄位建立索引呢?

一般說來,索引應建立在那些將用於JOIN,WHERE判斷和ORDERBY排序的欄位上。儘量不要對資料庫中某個含有大量重複的值的欄位建立索引。對於一個ENUM型別的欄位來說,出現大量重複值是很有可能的情況

例如customerinfo中的“province”..欄位,在這樣的欄位上建立索引將不會有什麼幫助;相反,還有可能降低資料庫的效能。我們在建立表的時候可以同時建立合適的索引,也可以使用ALTERTABLE或CREATEINDEX在以後建立索引。此外,MySQL從版本3.23.23開始支援全文索引和搜尋。全文索引在MySQL中是一個FULLTEXT型別索引,但僅能用於MyISAM型別的表。對於一個大的資料庫,將資料裝載到一個沒有FULLTEXT索引的表中,然後再使用ALTERTABLE或CREATEINDEX建立索引,將是非常快的。但如果將資料裝載到一個已經有FULLTEXT索引的表中,執行過程將會非常慢。

8、優化的查詢語句

絕大多數情況下,使用索引可以提高查詢的速度,但如果SQL語句使用不恰當的話,索引將無法發揮它應有的作用。

下面是應該注意的幾個方面。

  • 首先,最好是在相同型別的欄位間進行比較的操作。

    在MySQL3.23版之前,這甚至是一個必須的條件。例如不能將一個建有索引的INT欄位和BIGINT欄位進行比較;但是作為特殊的情況,在CHAR型別的欄位和VARCHAR型別欄位的欄位大小相同的時候,可以將它們進行比較。

  • 其次,在建有索引的欄位上儘量不要使用函式進行操作。

例如,在一個DATE型別的欄位上使用YEAE()函式時,將會使索引不能發揮應有的作用。所以,下面的兩個查詢雖然返回的結果一樣,但後者要比前者快得多。

  • 第三,在搜尋字元型欄位時,我們有時會使用LIKE關鍵字和萬用字元,這種做法雖然簡單,但卻也是以犧牲系統性能為代價的。

例如下面的查詢將會比較表中的每一條記錄。


SELECT*FROMbooks

WHEREnamelike"MySQL%"

但是如果換用下面的查詢,返回的結果一樣,但速度就要快上很多:


SELECT*FROMbooks

WHEREname>="MySQL"andname<"MySQM"

最後,應該注意避免在查詢中讓MySQL進行自動型別轉換,因為轉換過程也會使索引變得不起作用。

相關推薦

資料庫-試題-MySQL資料庫優化方法

1、選取最適用的欄位屬性 MySQL可以很好的支援大資料量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在建立表的時候,為了獲得更好的效能,我們可以將表中欄位的寬度設得儘可能小。 例如,在定義郵政編碼這個欄位時,如果將其設定為CHAR(2

華為試題資料庫sql優化方案

對於資料庫分割槽欄位,索引欄位,基本資料型別如何在sql進行優化查詢 答案:我們應該在過濾條件使用順序調整成分割槽條件/索引條件/基本資料型別條件 資料庫分割槽 是一種物理資料庫設計技術,DBA和資料庫建模人員對其相當熟悉。雖然分割槽技術可以實現很多效果,但其主要目的是

MySQL試題(六)資料庫的分庫分表原理詳解

對使用者而言,分割槽表是一個獨立的邏輯表,但是底層MySQL將其分成了多個物理子表,這對使用者來說是透明的,每一個分割槽表都會使用一個獨立的表文件。如圖所示:MySQL將表分成多個物理字表,客戶端並無感知,仍然認為操作的是一個表。建立表時使用partition by子句定義每個分割槽存放的資料,執行查詢時,優

資料庫遠端】MySQL資料庫開啟遠端連線方法

Mysql安裝後,預設不能外網直接訪問的,只能本機訪問,但是很多使用者需要外網訪問來備份資料、修改資料或者呼叫資料,mysql如何開啟遠端連線呢?下面就是MySQL資料庫開啟遠端連線方法。 登陸mysql操作命令如下直接複製即可 1.下面的命令是給予任何主機訪問資料的許可權 mysql&

那些java試題資料庫常問的!你會了多少!

資料庫裡面的索引和約束是什麼 用SQL語句實現oracle分頁查詢。   小編是一個有著5年工作經驗的java程式設計師,對於java,自己有做資料的整合,一個完整學習java的路線,學習資料和工具,相信這裡有很多學習java的小夥伴,我創立了一個20

Java試題2018---資料庫

一、運算子 a.算數運算子 +:  insert into sums values(12,13,age+height);//age和height型別是int。  select 1+3; -:  insert into sums values(12,13,

轉載: JAVA企業試題精選 資料庫11-20

1.11.請說明資料庫主鍵,外來鍵的作用 參考答案:   主鍵作用:能保證設定主鍵的列非空且唯一.另外,在定義主鍵時,如果這列之前沒有索引,系統會為其建立唯一性索引   外來鍵作用:能保證設定外來鍵的列取值必須匹配父表中已有的值.通過外來鍵可以與同一張表的

資料庫】:MySQL資料庫優化

1. MySQL架構 MySQL整體架構圖如下: 2. 查詢執行流程 查詢執行的流程是這樣的: 連線 客戶端發起一條Query請求,監聽客戶端的‘連線管理模組’接收請求 將請求轉發到‘連線進/執行緒模組’ 呼叫‘使用者模組’來進行授權檢查 通過

Java試題資料庫三正規化是什麼?

什麼是正規化? 簡言之就是,資料庫設計對資料的儲存效能,還有開發人員對資料的操作都有莫大的關係。所以建立科學的,規範的的資料庫是需要滿足一些規範的來優化資料資料儲存方式。在關係型資料庫中這些規範就可以稱為正規化。   什麼是三大正規化? 第一正規化(1NF):強調的是列的原子性,即列不能夠

試題資料庫索引及B樹、B+樹詳解

最近準備找一個實習,所以接下來,會通過其他人分享的面經陸續的總結面試中經常遇到的題 今天是關於資料庫索引,以及具體的實現(B樹及B+樹) 本文參考自兩篇部落格(個人認為是最好的相關部落格了) 資料庫索引部分:http://blog.csdn.net/weilianglian

試題:刪除資料庫中帶有重複欄位的記錄,只保留一條記錄

select * from tablename where 重複欄位1 in (select 重複欄位1 from tablename group by 重複欄位1,重複欄位2 having count(*)>1)。SQL重複記錄查詢方法:1、查詢表中多餘的重複記錄,重

Python試題資料庫和快取

會的小夥伴請在下方留言吧!^_^ 資料庫和快取(46題) 1: 列舉常見的關係型資料庫和非關係型都有那些? 2: MySQL常見資料庫引擎及比較? 3: 簡述資料三大正規化? 4: 什麼是事務?MySQL如何支援事務? 5: 簡述資料庫設計中一對

MySQL試題之如何優化一條有問題的SQL語句?

類型 審查 存儲ip code 減少 提高 利用 存儲空間 not 如何優化一條有問題的sql語句? 針對sql語句的優化。我們可以從如下幾個角度去分析 回歸到表的設計層面,數據類型選擇是否合理 大表碎片的整理是否完善 表的統計信息,是不是準確的 審查表的執

Java試題大全(資料庫部分三)

11、Oracle資料常用的備份與恢復? Oracle的備份與恢復有三種標準的模式,大致分為兩大類,備份恢復(物理上的)以及匯入匯出(邏輯上的),而備份恢復又可以根據資料庫的工作模式分為非歸檔模式(Nonarchivelog-style)和歸檔模式(Arch

MySQL查詢優化方法總結

系統表 所有 全文檢索 更新 系統 and 插入 upd 一個 1.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 2.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及頻繁的

試題: mysql 數據庫去重

AI rds In line 面試總結 engine fault bsp row mysql去重面試總結 前言:題目大概是這樣的。 建表: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE TABLE `tes

試題: mysql 數據庫未看9

tle roo 相關信息 lex 需要 原則 right SM ont 總結的一些MySQL數據庫面試題 2016年06月16日 11:41:18 閱讀數:4950 一、sql語句應該考慮哪些安全性? (1)防止sql註入,對特殊字符進行轉義,過濾或者使用預編

十道海量數據處理試題與十個方法大總結

面試題 線性 set TE 連續子序列 文本文 過程 現在 動態規劃 1. 給定a、b兩個文件,各存放50億個url,每個url各占64字節,內存限制是4G,讓你找出a、b文件共同的url? 方案1:可以估計每個文件安的大小為50G×64=320G,遠遠大於內存限制的4G。

自己實戰整理試題--Mysql(帶答案,不斷更新)

mysql目前用的版本? 5.1.21;目前最高5.7.* left join,right join,inner join? left join(左連線) 返回包括左表中的所有記錄和右表中連線欄位相等的記錄  right join(右連線) 返回包括右表中的所有記錄和左

十道海量資料處理試題與十個方法大總結:

轉載之處:http://blog.csdn.net/liuqiyao_01/article/details/26567237 筆試 = (資料結構+演算法) 50%+ (計算機網路 + 作業系統)30% +邏輯智力題10%  + 資料庫5% + 歪門邪道題5%,而面