MySOL程序員面試分類模擬題2_第1頁
MySOL程序員面試分類模擬題2_第2頁
MySOL程序員面試分類模擬題2_第3頁
MySOL程序員面試分類模擬題2_第4頁
MySOL程序員面試分類模擬題2_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

MySOL程序員面試分類模擬題2一、簡答題1.

虛擬地址、邏輯地址、線性地址、物理地址有什么區(qū)別?正確答案:虛擬地址是指由程序產(chǎn)生的由段選擇符和段內(nèi)偏移地址組成的地址。這兩部分組成的地址并沒有直接(江南博哥)訪問物理內(nèi)存,而是要通過分段地址的變換處理后才會對應(yīng)到相應(yīng)的物理內(nèi)存地址。

邏輯地址是指由程序產(chǎn)生的段內(nèi)偏移地址。有時直接把邏輯地址當(dāng)成虛擬地址,兩者并沒有明確的界限。

線性地址是指虛擬地址到物理地址變換之間的中間層,是處理器可尋址的內(nèi)存空間(稱為線性地址空間)中的地址。程序代碼會產(chǎn)生邏輯地址,或者說是段中的偏移地址,加上相應(yīng)段基址就生成了一個線性地址。如果啟用了分頁機(jī)制,那么線性地址可以再經(jīng)過變換產(chǎn)生物理地址。若是沒有采用分頁機(jī)制,那么線性地址就是物理地址。

物理地址是指現(xiàn)在CPU外部地址總線上的尋址物理內(nèi)存的地址信號,是地址變換的最終結(jié)果。

虛擬地址到物理地址的轉(zhuǎn)化方法是與體系結(jié)構(gòu)相關(guān)的,一般有分段與分頁兩種方式。以x86CPU為例,分段、分頁都是支持的。內(nèi)存管理單元負(fù)責(zé)從虛擬地址到物理地址的轉(zhuǎn)化。邏輯地址是段標(biāo)識+段內(nèi)偏移量的形式,MMU通過查詢段表,可以把邏輯地址轉(zhuǎn)化為線性地址。如果CPU沒有開啟分頁功能,那么線性地址就是物理地址;如果CPU開啟了分頁功能,MMU還需要查詢頁表來將線性地址轉(zhuǎn)化為物理地址:邏輯地址(段表)→線性地址(頁表)→物理地址。

映射是一種多對一的關(guān)系,即不同的邏輯地址可以映射到同一個線性地址上;不同的線性地址也可以映射到同一個物理地址上。而且,同一個線性地址在發(fā)生換頁以后,也可能被重新裝載到另外一個物理地址上,所以這種多對一的映射關(guān)系也會隨時間發(fā)生變化。

2.

靜態(tài)鏈接庫與動態(tài)鏈接庫有什么區(qū)別?正確答案:靜態(tài)鏈接庫就是使用的.lib文件,庫中的代碼最后需要鏈接到可執(zhí)行文件中去,所以靜態(tài)鏈接的可執(zhí)行文件一般比較大一些。

動態(tài)鏈接庫是一個包含可由多個程序同時使用的代碼和數(shù)據(jù)的庫,它包含函數(shù)和數(shù)據(jù)的模塊的集合。程序文件(如.exe文件或.dll文件)在運行時加載這些模塊(也即所需的模塊映射到調(diào)用進(jìn)程的地址空間)。

靜態(tài)鏈接庫和動態(tài)鏈接庫的相同點是它們都實現(xiàn)了代碼的共享。不同點是靜態(tài)鏈接庫.lib文件中的代碼被包含在調(diào)用的.exe文件中,該.lib文件中不能再包含其他動態(tài)鏈接庫或者靜態(tài)鏈接庫了。而動態(tài)鏈接庫.dll文件可以被調(diào)用的.exe動態(tài)地“引用”和“卸載”,該.dll文件中可以包含其他動態(tài)鏈接庫或者靜態(tài)鏈接庫。

3.

MySQL有哪些數(shù)據(jù)類型?正確答案:MySQL中定義數(shù)據(jù)字段的類型對數(shù)據(jù)庫的優(yōu)化是非常重要的。MySQL支持多種類型,大致可以分為三類:數(shù)值、日期/時間和字符串(字符)類型。

1.?dāng)?shù)值類型

下表介紹了數(shù)值類型的特性。

類型大小范圍(有符號)曩范圍(無符號)。用途整數(shù)類型TINYINT1字節(jié)(-128,127)(0,255)小整數(shù)值、微小SMALLINT2字節(jié)(-32768,32767)(0,65535)大整數(shù)值、小MEDIUMINT3字節(jié)(-8388608,8388607)(0,16777215)大整數(shù)值、中等大小INT或INTEGER4字節(jié)(-2147483648,2147483647)(0,4294967295)大整數(shù)值、普通大小BIGINT8字節(jié)(-9233372036854775808,9223372036854775807)(0,18446744073709551615)極大整數(shù)值、大帶小數(shù)的類型FLOAT4字節(jié)(-3.402823466E+38,1.175494351E-38),0,(1.175494351E-38,3.402823466351E+38)0,(1.175494351E-38,3.402823466E+38)單精度浮點數(shù)值DOUBLE8字節(jié)(1.7976931348623157E+308,2.2250738585072014E-308),0,(2.2250738585072014E-308,1.7976931348623157E+308)0,(2.2250738585072014E-308,1.7976931348623157E+308)雙精度浮點數(shù)值DECIMAL對DECIMAL(M,D),若M>D,則為M+2否則,為D+2依賴于M和D的值依賴于M和D的值小數(shù)值、定點數(shù)2.日期和時間類型

表示時間值的日期和時間類型為DATETIME、DATE、TIMESTAMP、TIME和YEAR。每個時間類型有一個有效值范圍和一個“零”值,當(dāng)指定不合法的MySQL不能表示的值時使用“零”值。下表介紹了日期和時間類型的特性。

類型大小(字節(jié))范圍格式用途及注意事項DATE31000-01-01~9999-12-31YYYY-MM-DD日期值TIME3'-838:59:59'~'838:59:59'HH:MM:SS時間值或持續(xù)時間YEAR11901~2155YYYY年份值DATETIME5+小數(shù)位1000-01-0100:00:00.000000~9999-12-3123:59:59.999999YYYY-MM-DDDDHH:MM:SS混合日期和時間值。對于DATATIME類型的字段,在MySQL5.64以前是8個字節(jié)(不能存儲小數(shù)位),之后的長度為5個字節(jié)再加上小數(shù)位字節(jié)數(shù)。DATATIME最大小數(shù)位是6。若小數(shù)位為1或2,則總字節(jié)數(shù)為6(5+1):若小數(shù)位為3或4,則總字節(jié)數(shù)為7(5+2):若小數(shù)位為5或6,則總字節(jié)數(shù)為8(5+3)TIMESTAMP81970-01-0100:00:01.000000~2038-01-1903:14:07.999999YYYYMMDDHHMMSS混合日期和時間值,時間戳。TIMESTAMP最大小數(shù)位是6使用日期類型需要注意如下幾點內(nèi)容:

(1)如果要記錄年月日時分秒,并且記錄的年份比較久遠(yuǎn),那么最好使用DATETIME,而不要使用TIMESTAMP,因為TIMESTAMP表示的日期范圍比DATETIME要短得多。

(2)如果記錄的日期需要讓不同時區(qū)的用戶使用,那么最好使用TIMESTAMP,因為日期類型中只有它能夠和實際時區(qū)相對應(yīng)。

舉例如下所示:

3.字符串類型

字符串類型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。下表介紹了字符串類型的特性。

類型大小(字節(jié))用途注意CHAR0~255定長字符串頻繁改變的列建議用CHAR類型VARCHIAR0~65535變長字符串

TINYBLOB0~255不超過255個字符的二進(jìn)制字符串

TINYTEXT0~255短文本字符串

BLOB0~65535二進(jìn)制形式的長文本數(shù)據(jù)

TEXT0~65535長文本數(shù)據(jù)、VARCHAR的加長增強版

MEDIUMBLOB0~16777215二進(jìn)制形式的中等長度文本數(shù)據(jù)

MEDIUMTEXT0~16777215中等長度文本數(shù)據(jù)

LOGNGBLOB0~4294967295二進(jìn)制形式的極大文本數(shù)據(jù)

LONGTEXT0~4294967295極大文本數(shù)據(jù)

ENUM1~2枚舉類型

SET1~8類似于枚舉類型,但是,SET類型一次可以選取多個成員,而ENUM只能選一個

字符類型需要注意如下幾點內(nèi)容:

(1)CHAR和VARCHAR類型類似,但它們保存和檢索的方式不同。它們的最大長度和尾部空格是否被保留等方面也不同。在存儲或檢索過程中不進(jìn)行大小寫轉(zhuǎn)換。

(2)BINARY和VARBINARY類似于CHAR和VARCHAR,不同的是它們包含二進(jìn)制字符串而不要非二進(jìn)制字符串。也就是說,它們包含字節(jié)字符串而不是字符字符串。這說明它們沒有字符集,并且排序和比較基于列值字節(jié)的數(shù)值。

(3)BLOB是一個二進(jìn)制大對象,可以容納可變數(shù)量的數(shù)據(jù)。有4種BLOB類型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它們的區(qū)別只是可容納值的最大長度不同。

(4)有4種TEXT類型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。這些對應(yīng)4種BLOB類型,有相同的最大長度和存儲需求。

字符串舉例如下所示:

mysql>CREATETABLEt6(sexenum('F','M','UN'));

4.

什么是內(nèi)存碎片?什么是內(nèi)碎片?什么是外碎片?正確答案:內(nèi)存碎片是由于多次進(jìn)行內(nèi)存分配造成的,當(dāng)進(jìn)行內(nèi)存分配時,內(nèi)存格式一般為:(用戶使用段)(空白段)(用戶使用段),當(dāng)空白段很小的時候可能不能提供給用戶足夠多的空間,比如夾在中間的空白段的大小為5,而用戶需要的內(nèi)存大小為6,這樣會產(chǎn)生很多的間隙造成使用效率下降,這些很小的空隙稱為碎片。

內(nèi)碎片:分配給程序的存儲空間沒有用完,有一部分是程序不使用,但其他程序也沒法用的空間。內(nèi)碎片是處于區(qū)域內(nèi)部或頁面內(nèi)部的存儲塊,占有這些區(qū)域或頁面的進(jìn)程并不使用這個存儲塊,而在進(jìn)程占有這塊存儲塊時,系統(tǒng)無法利用它,直到進(jìn)程釋放它或進(jìn)程結(jié)束時,系統(tǒng)才有可能利用這個存儲塊。

外碎片:由于空間太小,小到無法給任何程序分配(不屬于任何進(jìn)程)存儲空間。外部碎片是出于任何已分配區(qū)域或頁面外部的空閑存儲塊,這些存儲塊的總和可以滿足當(dāng)前申請的長度要求,但是由于它們的地址不連續(xù)或其他原因,使得系統(tǒng)無法滿足當(dāng)前申請。

內(nèi)碎片和外碎片是一對矛盾體,一種特定的內(nèi)存分配算法,很難同時解決好內(nèi)碎片和外碎片的問題,只能根據(jù)應(yīng)用特點進(jìn)行取舍。

5.

MySQL中LENGTH和CHAR_LENGTH的區(qū)別是什么?正確答案:LENGTH和CHAR_LENGTH是MySQL中獲取字符串長度的兩個函數(shù)。函數(shù)LENGTH是計算字段的長度,單位為字節(jié),1個漢字算3個字節(jié),1個數(shù)字或字母算1個字節(jié)。CHAR_LENGTH(str)返回值為字符串str的長度,單位為字符。CHARACTER_LENGTH()是CHAR_LENGTH()的同義詞。對于函數(shù)CHAR_LENGTH來說,一個多字節(jié)字符算作一個單字符。Latin1字符的這兩個函數(shù)返回結(jié)果是相同的,但是對于Unicode和其他編碼來說,它們是不同的。例如,對于一個包含5個2字節(jié)字符集的字符串來說,LENGTH()返回值為10,而CHAR_LENGTH()的返回值為5。

示例如下:

6.

如何對MySQL進(jìn)行優(yōu)化?正確答案:一個成熟的數(shù)據(jù)庫架構(gòu)并不是一開始設(shè)計就具備高可用、高伸縮等特性,它是隨著用戶量的增加,基礎(chǔ)架構(gòu)才逐漸完善。

1.?dāng)?shù)據(jù)庫的設(shè)計

1)盡量讓數(shù)據(jù)庫占用更小的磁盤空間。

2)盡可能使用更小的整數(shù)類型。

3)盡可能地定義字段為NOTNULL,除非這個字段需要NULL。

4)如果沒有用到變長字段(例如VARCHAR)的話,那么就采用固定大小的記錄格式,例如CHAR。

5)只創(chuàng)建確實需要的索引。索引有利于檢索記錄,但是不利于快速保存記錄。如果總是要在表的組合字段上做搜索,那么就在這些字段上創(chuàng)建索引。索引的第一部分必須是最常使用的字段。

6)所有數(shù)據(jù)都得在保存到數(shù)據(jù)庫前進(jìn)行處理。

7)所有字段都得有默認(rèn)值。

2.系統(tǒng)的用途

1)盡量使用長連接。

2)通過EXPLAIN查看復(fù)雜SQL的執(zhí)行方式,并進(jìn)行優(yōu)化。

3)如果兩個關(guān)聯(lián)表要做比較,那么做比較的字段必須類型和長度都一致。

4)LIMIT語句盡量要跟ORDERBY或DISTINCT搭配使用,這樣可以避免做一次FULLTABLESCAN。

5)如果想要清空表的所有紀(jì)錄,那么建議使用TRuNCATETABLETABLENAME而不是DELETEFROMTABLENAME。

6)在一條INSERT語句中采用多重記錄插入格式,而且使用loaddatainfile來導(dǎo)入大量數(shù)據(jù),這比單純的INSERT快很多。

7)如果DATE類型的數(shù)據(jù)需要頻繁地做比較,那么盡量保存為UNSIGNEDINT類型,這樣可以加快比較的速度。

3.系統(tǒng)的瓶頸

(1)磁盤搜索

并行搜索。把數(shù)據(jù)分開存放到多個磁盤中,這樣能加快搜索時間。

(2)磁盤讀寫(I/O)

可以從多個媒介中并行的讀取數(shù)據(jù)。

(3)CPU周期

數(shù)據(jù)存放在主內(nèi)存中。這樣就得增加CPU的個數(shù)來處理這些數(shù)據(jù)。

(4)內(nèi)存帶寬

當(dāng)CPU要將更多的數(shù)據(jù)存放到CPU的緩存中來的話,內(nèi)存的帶寬就成了瓶頸。

4.?dāng)?shù)據(jù)庫參數(shù)優(yōu)化

MySQL常用的有兩種存儲引擎,分別是MyISAM和InnoDB。每種存儲引擎的參數(shù)比較多,以下列出主要影響數(shù)據(jù)庫性能的參數(shù)。

(1)公共參數(shù)默認(rèn)值

1)max_connections=151#同時處理最大連接數(shù),推薦設(shè)置最大連接數(shù)是上限連接數(shù)的80%左右。

2)sort_buffer_size=2M#查詢排序時緩沖區(qū)大小,只對ORDERBY和GROUPBY起作用,可增大此值為16M。

3)open_files_limit=1024#打開文件數(shù)限制,如果showglobalstareslike'open_files'查看的值等于或者大于open_files_limit值時,程序會無法連接數(shù)據(jù)庫或卡死。

(2)MyISAM參數(shù)默認(rèn)值

1)key_buffer_size=16M#索引緩存區(qū)大小,一般設(shè)置物理內(nèi)存的30%~40%。

2)read_buffer_size=128K#讀操作緩沖區(qū)大小,推薦設(shè)置16M或32M。

3)query_cache_type=ON#打開查詢緩存功能。

4)query_cache_limit=1M#查詢緩存限制,只有1M以下查詢結(jié)果才會被緩存,以免結(jié)果數(shù)據(jù)較大把緩存池覆蓋。

5)query_cache_size=16M#查看緩沖區(qū)大小,用于緩存SELECT查詢結(jié)果,下一次有同樣SELECT查詢將直接從緩存池返回結(jié)果,可適當(dāng)成倍增加此值。

(3)InnoDB參數(shù)默認(rèn)值

1)innodb_buffer_pool_size=128M#索引和數(shù)據(jù)緩沖區(qū)大小,一般設(shè)置物理內(nèi)存的60%~70%。

2)innodb_buffer_pool_instances=1#緩沖池實例個數(shù),推薦設(shè)置4個或8個。

3)innodb_flush_log_at_trx_commit=1#關(guān)鍵參數(shù),0代表大約每秒寫入到日志并同步到磁盤,數(shù)據(jù)庫故障會丟失1s左右事務(wù)數(shù)據(jù)。1為每執(zhí)行一條SQL后寫入到日志并同步到磁盤,I/O開銷大,執(zhí)行完SQL要等待日志讀寫,效率低。2代表只把日志寫入到系統(tǒng)緩存區(qū),再每秒同步到磁盤,效率很高,如果服務(wù)器故障,才會丟失事務(wù)數(shù)據(jù)。對數(shù)據(jù)安全性要求不是很高的推薦設(shè)置2,性能高,修改后效果明顯。

4)innodb_file_per_table=OFF#默認(rèn)是共享表空間,共享表空間idbdata文件不斷增大,影響一定的I/O性能。推薦開啟獨立表空間模式,每個表的索引和數(shù)據(jù)都存在自己獨立的表空間中,可以實現(xiàn)單表在不同數(shù)據(jù)庫中移動。

5)innodb_log_buffer_size=8M#日志緩沖區(qū)大小,由于日志最長每秒鐘刷新一次,所以一般不用超過16M

5.系統(tǒng)內(nèi)核優(yōu)化

大多數(shù)MySQL都部署在Linux系統(tǒng)上,所以,操作系統(tǒng)的一些參數(shù)也會影響到MySQL性能,以下參數(shù)的設(shè)置可以對Linux內(nèi)核進(jìn)行適當(dāng)優(yōu)化。

1)net.ipv4.tcp_fin_timeout=30#TIME_WAIT超時時間,默認(rèn)是60s。

2)net.ipv4.tcp_tw_reuse=1#1表示開啟復(fù)用,允許TIME_WAITsocket重新用于新的TCP連接,0表示關(guān)閉。

3)net.ipv4.tcp_tw_recycle=1#1表示開啟TIME_WAITsocket快速回收,0表示關(guān)閉。

4)net.ipv4.tcp_max_tw_buckets=4096#系統(tǒng)保持TIME_WAITsocket最大數(shù)量,如果超出這個數(shù),系統(tǒng)將隨機(jī)清除一些TIME_WAIT并打印警告信息。

5)net.ipv4.tcp_max_syn_backlog=4096#進(jìn)入SYN隊列最大長度,加大隊列長度可容納更多的等待連接。

在Linux系統(tǒng)中,如果進(jìn)程打開的文件句柄數(shù)量超過系統(tǒng)默認(rèn)值1024,就會提示“toomanyfilesopen”信息,所以,要調(diào)整打開文件句柄限制。

6)#vi/etc/security/limits.conf#加入以下配置,*代表所有用戶,也可以指定用戶,重啟系統(tǒng)生效。

7)*softnofile65535。

8)*hardnofile65535。

9)#ulimit-SHn65535#立刻生效。

6.硬件配置

硬件配置應(yīng)加大物理內(nèi)存,提高文件系統(tǒng)性能。Linux內(nèi)核會從內(nèi)存中分配出緩存區(qū)(系統(tǒng)緩存和數(shù)據(jù)緩存)來存放熱數(shù)據(jù),通過文件系統(tǒng)延遲寫入機(jī)制,等滿足條件時(如緩存區(qū)大小到達(dá)一定百分比或者執(zhí)行sync命令)才會同步到磁盤。也就是說物理內(nèi)存越大,分配緩存區(qū)越大,緩存數(shù)據(jù)越多。當(dāng)然,服務(wù)器故障會丟失一定的緩存數(shù)據(jù)??梢圆捎肧SD(SolidStateDrives,固態(tài)硬盤)硬盤代替SAS(SerialAttachedSCSI,串行連接SCSI)硬盤,將RAID(RedundantArraysofIndependentDisks,磁盤陣列)級別調(diào)整為RAID1+0,相對于RAID1和RAID5它有更好的讀寫性能(IOPS,Input/OutputOperationsPerSecond,即每秒進(jìn)行讀寫(I/O)操作的次數(shù)),畢竟數(shù)據(jù)庫的壓力主要來自磁盤I/O方面。

7.SQL優(yōu)化

執(zhí)行緩慢的SQL語句大約能消耗數(shù)據(jù)庫70%~90%的CPU資源,而SQL語句獨立于程序設(shè)計邏輯,相對于對程序源代碼的優(yōu)化,對SQL語句的優(yōu)化在時間成本和風(fēng)險上的代價都很低。SQL語句可以有不同的寫法,下面分別來看看。

1)在MySQL5.5及其以下版本中避免使用子查詢。

例如,在MySQL5.5版本里,若執(zhí)行下面的SQL語句,則內(nèi)部執(zhí)行計劃器是這樣執(zhí)行的:先查外表再匹配內(nèi)表,而不是先查內(nèi)表T2。所以,當(dāng)外表的數(shù)據(jù)很大時,查詢速度就會非常慢。

SELECT*FROMT1WHEREIDIN(SELECTIDFROMT2WHERENAME='xiaomaimiao');

在MySQL5.6版本里,采用JOIN關(guān)聯(lián)方式對其進(jìn)行了優(yōu)化,這條SQL會自動轉(zhuǎn)換為:

SELECTT1.*FROMT1JOINT2ONT1.ID=T2.ID;

需要注意的是,該優(yōu)化只針對SELECT有效,對UPDATE或DELETE子查詢無效,故生產(chǎn)環(huán)境應(yīng)避免使用子查詢。

2)避免函數(shù)索引。

例如下面的SQL語句會使用全表掃描:

SELECT*FROMTWHEREYEAR(D)>=2016;

由于MySQL不像Oracle那樣支持函數(shù)索引,即使D字段有索引,也會使用全表掃描。為例能使用到這一列的索引,應(yīng)改為如下的SQL語句:

SELECT*FROMTWHERED>='2016-01-01';

3)用IN來替換OR。

低效查詢:

SELECT*FROMTWHERELOC_ID=10ORLOC_ID=20ORLOC_ID=30;

高效查詢:

SELECT*FROMTWHERELOC_ININ(10,20,30);

4)在LIKE中雙百分號無法使用到索引。

SELECT*FROMtWHEREnameLIKE'%de%';

SELECT*FROMtWHEREnameLIKE'de%';

在以上SQL語句中,第一句SQL無法使用索引,而第二句可以使用索引。目前只有MySQL5.7及以上版本支持全文索引。

5)讀取適當(dāng)?shù)挠涗汱IMITM,N。

SELECT*FROMtWHERE1;

SELECT*FROMtWHERE1LIMIT10;

6)避免數(shù)據(jù)類型不一致。

SELECT*FROMTWHEREID='19';

由于以上SQL中ID為數(shù)值型,所以應(yīng)該去掉過濾條件中數(shù)值19的雙引號:

SELECT*FROMTWHEREID=19;

7)分組統(tǒng)計可以禁止排序。

SELECTGOODS_ID,COUNT(*)FROMTGROUPBYGOODS_ID;

默認(rèn)情況下,MySQL會對所有GROUPBYcol1,col2…的字段進(jìn)行排序。如果查詢包括GROUPBY,那么想要避免排序結(jié)果的消耗,則可以指定ORDERBYNULL禁止排序,如下所示:

SELECTGOODS_ID,COUNT(*)FROMTGROUPBYGOODS_IDORDERBYNULL;

8)避免隨機(jī)取記錄。

SELECT*FROMT1WHERE1=1ORDERBYRAND()LIMIT4;

由于MySQL不支持函數(shù)索引,所以以上SQL會使用全表掃描,可以修改為如下的SQL語句:

SELECT*FROMT1WHEREID>=CEIL(RAND()*1000)LIMIT4;

9)禁止不必要的ORDERBY排序。

SELECTCOUNT(1)FROMT1JOINT2ONT1.ID=T2.IDWHERE1=1ORDERBYT1.IDDESC;

由于計算的是總量,所以沒有必要去排序,可以去掉排序語句,如下所示:

SELECTCOUNT(1)FROMT1JOINT2ONT1.ID=T2.ID;

10)盡量使用批量INSERT插入。

下面的SQL語句可以使用批量插入:

INSERTINTOt(id,name)VALUES(1,'xiaolu');

INSERTINTOt(id,name)VALUES(2,'xiaobai');

INSERTINTOt(id,name)VALUES(3,'xiaomaimiao');

修改后的SQL語句:

INSERTINTOt(id,name)VALUES(1,'xiaolu'),(2,'xiaobai'),(3,'xiaomaimiao');

7.

MySQL中的隱式類型轉(zhuǎn)換(Implicittypeconversion)正確答案:當(dāng)對不同類型的值進(jìn)行比較的時候,為了使得這些數(shù)值可比較(也可以稱為類型的兼容性),MySQL會做一些隱式類型轉(zhuǎn)化(Implicittypeconversion)。例如:

很明顯,在上面的SQL語句的執(zhí)行過程中就出現(xiàn)了隱式轉(zhuǎn)化。并且從結(jié)果可以判斷出,在第一條SQL中,將字符串的“1”轉(zhuǎn)換為數(shù)字1,而在第二條的SQL中,將數(shù)字2轉(zhuǎn)換為字符串“2”。

MySQL也提供了CAST()函數(shù),可以使用它明確地把數(shù)值轉(zhuǎn)換為字符串。當(dāng)使用CONCAT()函數(shù)的時候,也可能會出現(xiàn)隱式轉(zhuǎn)化,因為它希望的參數(shù)為字符串形式,但是如果傳遞的不是字符串的話,那么它會發(fā)生隱式類型轉(zhuǎn)換:

1rowinset(0.00sec)

隱式類型轉(zhuǎn)換的規(guī)則為:

1)當(dāng)兩個參數(shù)至少有一個是NULL時,比較的結(jié)果也是NULL。若使用<=>對兩個NULL做比較時則會返回1。這兩種情況都不需要做類型轉(zhuǎn)換。

2)當(dāng)兩個參數(shù)都是字符串時,會按照字符串來比較,不做類型轉(zhuǎn)換。

3)當(dāng)兩個參數(shù)都是整數(shù)時,按照整數(shù)來比較,不做類型轉(zhuǎn)換。

4)當(dāng)十六進(jìn)制的值和非數(shù)字做比較時,會被當(dāng)作二進(jìn)制串。

5)當(dāng)有一個參數(shù)是TIMESTAMP或DATETIME,并且另外一個參數(shù)是常量時,常量會被轉(zhuǎn)換為TIMESTAMP。

6)當(dāng)有一個參數(shù)是decimal類型時,如果另外一個參數(shù)是decimal或者整數(shù),那么會將整數(shù)轉(zhuǎn)換為decimal后進(jìn)行比較,如果另外一個參數(shù)是浮點數(shù),那么會把decimal轉(zhuǎn)換為浮點數(shù)進(jìn)行比較。

7)所有其他情況下,兩個參數(shù)都會被轉(zhuǎn)換為浮點數(shù)再進(jìn)行比較。

示例如下:

0.01a轉(zhuǎn)成double型被截斷成0.01,所以11+'0.01a'=11.01。上面可以看出11+'aa',由于操作符兩邊的類型不一樣且符合第7條,aa要被轉(zhuǎn)換成浮點型小數(shù),然而轉(zhuǎn)換失敗(字母被截斷),可以認(rèn)為轉(zhuǎn)成了0,整數(shù)11被轉(zhuǎn)成浮點型還是它自己,所以11+'aa'=11。'11a'和'11.0'轉(zhuǎn)換后都等于11。

如果在SQL的WHERE條件中,列名為字符串,而其值為數(shù)值,那么MySQL不會使用索引,這個規(guī)則和Oracle是一致的。

8.

事務(wù)的常見分類有哪些?正確答案:從事務(wù)理論的角度來看,可以把事務(wù)分為以下幾種類型:

●扁平事務(wù)(FlatTransactions)

●帶有保存點的扁平事務(wù)(FlatTransactionswithSavepoints)

●鏈?zhǔn)聞?wù)(ChainedTransactions)

●嵌套事務(wù)(NestedTransactions)

●分布式事務(wù)(DistributedTransactions)

下面分別介紹這幾種類型:

1)扁平事務(wù)是事務(wù)類型中最簡單的一種,但是在實際生產(chǎn)環(huán)境中,這可能是使用最頻繁的事務(wù),在扁平事務(wù)中,所有操作都處于同一層次,其由BEGlNWORK開始,由COMMITWORK或ROLLBACKWORK結(jié)束,其間的操作是原子的,要么都執(zhí)行,要么都回滾,因此,扁平事務(wù)是應(yīng)用程序成為原子操作的基本組成模塊。扁平事務(wù)雖然簡單,但是在實際環(huán)境中使用最為頻繁,也正因為其簡單,使用頻繁,故每個數(shù)據(jù)庫系統(tǒng)都實現(xiàn)了對扁平事務(wù)的支持。扁平事務(wù)的主要限制是不能提交或者回滾事務(wù)的某一部分,或分幾個步驟提交。

保存點(Savepoint)用來通知事務(wù)系統(tǒng)應(yīng)該記住事務(wù)當(dāng)前的狀態(tài),以便當(dāng)之后發(fā)生錯誤時,事務(wù)能回到保存點當(dāng)時的狀態(tài)。對于扁平的事務(wù)來說,隱式的設(shè)置了一個保存點,然而在整個事務(wù)中,只有這一個保存點,因此,回滾只能會滾到事務(wù)開始時的狀態(tài)。

扁平事務(wù)一般有三種不同的結(jié)果:①事務(wù)成功完成。在平常應(yīng)用中約占所有事務(wù)的96%。②應(yīng)用程序要求停止事務(wù)。比如應(yīng)用程序在捕獲到異常時會回滾事務(wù),約占事務(wù)的3%。③外界因素強制終止事務(wù)。如連接超時或連接斷開,約占所有事務(wù)的1%。

2)帶有保存點的扁平事務(wù)除了支持扁平事務(wù)支持的操作外,還允許在事務(wù)執(zhí)行過程中回滾到同一事務(wù)中較早的一個狀態(tài)。這是因為某些事務(wù)可能在執(zhí)行過程中出現(xiàn)的錯誤并不會導(dǎo)致所有的操作都無效,放棄整個事務(wù)不合乎要求,開銷太大。

3)鏈?zhǔn)聞?wù)是指一個事務(wù)由多個子事務(wù)鏈?zhǔn)浇M成,它可以被視為保存點模式的一個變種。帶有保存點的扁平事務(wù),當(dāng)發(fā)生系統(tǒng)崩潰時,所有的保存點都將消失,這意味著當(dāng)進(jìn)行恢復(fù)時,事務(wù)需要從開始處重新執(zhí)行,而不能從最近的一個保存點繼續(xù)執(zhí)行。鏈?zhǔn)聞?wù)的思想是:在提交一個事務(wù)時,釋放不需要的數(shù)據(jù)對象,將必要的處理上下文隱式地傳給下一個要開始的事務(wù),前一個子事務(wù)的提交操作和下一個子事務(wù)的開始操作合并成一個原子操作,這意味著下一個事務(wù)將看到上一個事務(wù)的結(jié)果,就好像在一個事務(wù)中進(jìn)行一樣。這樣,在提交子事務(wù)時就可以釋放不需要的數(shù)據(jù)對象,而不必等到整個事務(wù)完成后才釋放。其工作方式如下:

鏈?zhǔn)聞?wù)與帶有保存點的扁平事務(wù)的不同之處體現(xiàn)在:

①帶有保存點的扁平事務(wù)能回滾到任意正確的保存點,而鏈?zhǔn)聞?wù)中的回滾僅限于當(dāng)前事務(wù),即只能恢復(fù)到最近的一個保存點。

②對于鎖的處理,兩者也不相同,鏈?zhǔn)聞?wù)在執(zhí)行COMMIT后即釋放了當(dāng)前所持有的鎖,而帶有保存點的扁平事務(wù)不影響迄今為止所持有的鎖。

4)嵌套事務(wù)是一個層次結(jié)構(gòu)框架,由一個頂層事務(wù)(Top-LevelTransaction)控制著各個層次的事務(wù),頂層事務(wù)之下嵌套的事務(wù)被稱為子事務(wù)(Subtransaction),其控制著每一個局部的變換,子事務(wù)本身也可以是嵌套事務(wù)。因此,嵌套事務(wù)的層次結(jié)構(gòu)可以看成是一棵樹。

5)分布式事務(wù)通常是在一個分布式環(huán)境下運行的扁平事務(wù),因此,需要根據(jù)數(shù)據(jù)所在位置訪問網(wǎng)絡(luò)中不同節(jié)點的數(shù)據(jù)庫資源。例如,一個銀行用戶從招商銀行的賬戶向工商銀行的賬戶轉(zhuǎn)賬1000元,這里需要用到分布式事務(wù),因為不能僅調(diào)用某一家銀行的數(shù)據(jù)庫就完成任務(wù)。

9.

如何提高M(jìn)ySQL的安全性?正確答案:可以通過如下的方法來提高M(jìn)ySQL的安全性:

1)如果MySQL客戶端和服務(wù)器端的連接需要跨越并通過不可信任的網(wǎng)絡(luò),那么需要使用SSH隧道來加密該連接的通信。

2)使用setpassword語句來修改用戶的密碼,首先使用“mysql-uroot”登陸數(shù)據(jù)庫系統(tǒng),然后使用“UPDATEmysql.usersetpassword=password('newpwd')”來修改密碼,最后執(zhí)行“flushprivileges”就可以修改用戶的密碼了。

3)MySQL需要提防的攻擊有偷聽、篡改、回放、拒絕服務(wù)等,不涉及可用性和容錯方面。對所有的連接、查詢、其他操作使用基于ACL(AccessControlList,訪問控制列表)的安全措施來完成。

4)設(shè)置除了ROOT用戶外的其他任何用戶不允許訪問MySQL主數(shù)據(jù)庫中的USER表。如果存儲在LISER表中的用戶名與密碼一旦泄露,那么其他人可以隨意使用該用戶名和密碼登錄相應(yīng)的數(shù)據(jù)庫。因此,可以通過對USER表中用戶名和密碼進(jìn)行加密的方式來降低用戶名和密碼泄露帶來的風(fēng)險。

5)使用GRANT和REVOKE語句來執(zhí)行用戶訪問控制的工作。

6)不要使用明文密碼,而是使用MD5單向的HASH函數(shù)來設(shè)置密碼。

7)不要選用字典中的字來做密碼。

8)采用防火墻可以去掉50%的外部危險,讓數(shù)據(jù)庫系統(tǒng)躲在防火墻后面工作。

9)用telnetserver_host3306的方法測試,不允許從非信任網(wǎng)絡(luò)中訪問數(shù)據(jù)庫服務(wù)器的3306號TCP端口,需要在防火墻或路由器上做設(shè)定。

10)為了防止被惡意傳入非法參數(shù),例如WHEREID=234,當(dāng)輸入WHEREID=234OR1=1導(dǎo)致全部顯示,所以,在WEB的表單中禁止使用“或”來拼接字符串,在動態(tài)URL中加入%22代表雙引號、%23代表井號、%27代表單引號,傳遞未檢查過的值給MySQL數(shù)據(jù)庫是非常危險的。

11)在傳遞數(shù)據(jù)給MySQL時,檢查一下數(shù)據(jù)的大小。

12)應(yīng)用程序在連接到數(shù)據(jù)庫時應(yīng)該使用一般的用戶賬號,開放少數(shù)必要的權(quán)限給該用戶。

13)在各編程接口(例如C/C++/PHP/Perl/Java/JDBC等)中使用特定“逃脫字符”函數(shù),在網(wǎng)絡(luò)上使用MySQL數(shù)據(jù)庫時,一定少用傳輸明文的數(shù)據(jù),而用SSL和SSH的加密方式數(shù)據(jù)來傳輸。

14)學(xué)會使用tcpdump和strings工具來查看傳輸數(shù)據(jù)的安全性,例如tcpdump-1-ieth0-w-srcordstport3306strings。

15)確信在MySQL目錄中只有啟動數(shù)據(jù)庫服務(wù)的用戶才可以對文件有讀和寫的權(quán)限。

16)不許將SUPER權(quán)限授權(quán)給非管理用戶,SUPER權(quán)限可用于切斷客戶端連接、改變服務(wù)器運行參數(shù)狀態(tài)、控制復(fù)制數(shù)據(jù)庫的服務(wù)器。

17)文件權(quán)限不能授權(quán)給管理員以外的用戶,防止普通用戶使用命令loaddata'/etc/passwd'將OS密碼文件加載到數(shù)據(jù)庫中并使用SELECT查詢出來。

18)如果不相信DNS服務(wù)公司的服務(wù),那么可以在主機(jī)名稱允許表中只設(shè)置IP數(shù)字地址。

19)使用max_user_connections變量來使mysqld服務(wù)進(jìn)程對一個指定賬戶限定連接數(shù)。

20)啟動mysqld服務(wù)進(jìn)程的安全選項開關(guān),-local-infile=0或1,若是0,則客戶端程序就無法使用localloaddata了,授權(quán)的一個例子:GRANTINSERT(user)onmysql.userto'user_name'@'host_name',若使用-skip-grant-tables,則系統(tǒng)將對任何用戶的訪問不做任何訪問控制,但可以用mysqladminflush-privileges或mysqladminreload來開啟訪問控制。默認(rèn)情況是SHOWDATABASES語句對所有用戶開放,可以用-skip-show-databases來關(guān)閉掉。

10.

MySQL的分區(qū)表正確答案:表分區(qū)是指根據(jù)一定的規(guī)則,將數(shù)據(jù)庫中的一張表分解成多個更小的,容易管理的部分。從邏輯上看,只有一張表,但是底層卻是由多個物理分區(qū)組成,每個分區(qū)都是一個獨立的對象。分區(qū)有利于管理大表,體現(xiàn)了“分而治之”的理念。一個表最多支持1024個分區(qū)。

在MySQL5.6.1之前可以通過命令“showvariableslike'%have_partitioning%'”來查看MySQL是否支持分區(qū)。若have_partintioning的值為YES,則表示支持分區(qū)。從MySQL5.6.1開始,該參數(shù)已經(jīng)被去掉了,而是用SHOWPLUGINS來代替。若有partition行且STATUS列的值為ACTIVE,則表示支持分區(qū),如下所示:

此外,也可以使用表information_schema.plugins來查詢,如下所示:

MySQL支持的分區(qū)類型主要包括RANGE分區(qū)、LIST分區(qū)、HASH分區(qū)和KEY分區(qū)。分區(qū)表中對每個分區(qū)再次分割就是子分區(qū)(Subpartitioning),又稱為復(fù)合分區(qū)。在MySQL5.5中引入了COLUMNS分區(qū),細(xì)分為RANGECOLLIMNS和LISTCOLUMNS分區(qū)。引人COLUMNS分區(qū)解決了MySQL5.5版本之前RANGE分區(qū)和LIST分區(qū)只支持整數(shù)分區(qū),從而避免了需要額外的函數(shù)計算得到整數(shù)或者通過額外的轉(zhuǎn)換表來轉(zhuǎn)換為整數(shù)再分區(qū)的問題。

KEY分區(qū)類似HASH分區(qū),HASH分區(qū)允許使用用戶自定義的表達(dá)式,但KEY分區(qū)不允許使用用戶自定義的表達(dá)式。HASH僅支持整數(shù)分區(qū),而KEY分區(qū)支持除了BLOB和TEXT的其他類型的列作為分區(qū)鍵。KEY分區(qū)語法為:

PARTITIONBYKEY(EXP)PARTITIONS4;//EXP是零個或多個字段名的列表

在進(jìn)行KEY分區(qū)的時候,EXP可以為空,如果為空,那么默認(rèn)使用主鍵作為分區(qū)鍵。若沒有主鍵則會選擇非空唯一鍵作為分區(qū)鍵。

MySQL允許分區(qū)鍵值為NULL,分區(qū)鍵可能是一個字段或者一個用戶定義的表達(dá)式。一般情況下,MySQL在分區(qū)的時候會把NULL值當(dāng)作零值或者一個最小值進(jìn)行處理。需要注意以下幾點:

●RANGE分區(qū):NULL值被當(dāng)作最小值來處理。

●LIST分區(qū):NULL值必須出現(xiàn)在列表中,否則不被接受。

●HASH/KEY分區(qū):NULL值會被當(dāng)作零值來處理。

通過ALTERTABLE命令可以對分區(qū)進(jìn)行添加、刪除、重定義、合并和拆分等操作;通過information_schema.partitions可以查詢分區(qū)數(shù)、行數(shù)等信息;通過EXPLAINPARTITIONS可以查看分區(qū)表的執(zhí)行計劃。

11.

MySQL有哪幾個默認(rèn)數(shù)據(jù)庫?正確答案:在MySQL中,數(shù)據(jù)庫也可以稱為Schema。在安裝MySQL后,默認(rèn)有information_schema、mysql、performance_schema和sys這幾個數(shù)據(jù)庫。如下所示:

1.?dāng)?shù)據(jù)庫information_schema

informarion_schema是信息數(shù)據(jù)庫,是MySQL5.0新增的一個數(shù)據(jù)庫,其中保存著關(guān)于MySQL服務(wù)器所維護(hù)的所有其他數(shù)據(jù)庫的信息。informarion_schema提供了訪問數(shù)據(jù)庫元數(shù)據(jù)的方式。元數(shù)據(jù)是關(guān)于數(shù)據(jù)的數(shù)據(jù),例如數(shù)據(jù)庫名或表名,列的數(shù)據(jù)類型,訪問權(quán)限等。information_schema是一個虛擬數(shù)據(jù)庫,有數(shù)個只讀表,它們實際上是系統(tǒng)視圖(SYSTEMVIEW),而不是基本表,因此,在OS上無法看到與之相關(guān)的任何文件。所以,也只有該數(shù)據(jù)庫名在使用時,可以不區(qū)分大小寫,而剩下的mysql、performance_schema和sys數(shù)據(jù)庫在使用時都需要區(qū)分大小寫(都應(yīng)該小寫)。

2.?dāng)?shù)據(jù)庫mysql

這個是MySQL的核心數(shù)據(jù)庫,主要存儲著數(shù)據(jù)庫的用戶、權(quán)限設(shè)置、MySQL自己需要使用的控制和管理信息。它不可以被刪除,如果對MySQL不是很了解,那么也不要輕易修改這個數(shù)據(jù)庫里面的表信息。

3.?dāng)?shù)據(jù)庫performance_schema

這是從MySQL5.5版本開始新增的一個數(shù)據(jù)庫,主要用于收集數(shù)據(jù)庫服務(wù)器性能數(shù)據(jù)。該庫中所有表的存儲引擎均為PERFORMANCE_SCHEMA,而用戶是不能創(chuàng)建存儲引擎為PERFORMANCE_SCHEMA的表。這個功能從MySQL5.6.6開始,默認(rèn)是開啟的(在MySQL5.6.6版本以下默認(rèn)是關(guān)閉的),其值為1或ON表示啟用,為0或OFF表示關(guān)閉。需要注意的是,該參數(shù)是靜態(tài)參數(shù),只能寫在f中,不能動態(tài)修改,如下所示:

[mysqld]

performance_schema=ON

4.?dāng)?shù)據(jù)庫sys

MySQL5.7提供了sys系統(tǒng)數(shù)據(jù)庫。sys數(shù)據(jù)庫結(jié)合了information_schema和performance_schema的相關(guān)數(shù)據(jù),里面包含了一系列的存儲過程、自定義函數(shù)以及視圖來幫助DBA快速了解系統(tǒng)的元數(shù)據(jù)信息,為DBA解決性能瓶頸提供了巨大幫助。sys數(shù)據(jù)庫目前只包含一個表,表名為sys_config。

另外需要注意的一點是,在MySQL5.7以前還存在一個默認(rèn)的test庫,用于測試,而在MySQL5.7及其之后的版本中去掉了該庫。

12.

如何管理MySQk多實例?正確答案:MySQL多實例是指在一臺機(jī)器上開啟多個不同的服務(wù)端口(例如:3306、3307等),運行多個MySQL服務(wù)進(jìn)程,通過不同的Socket監(jiān)聽不同的服務(wù)端口來提供各自的服務(wù)。

MySQL多實例可以有效利用服務(wù)器資源,當(dāng)單個服務(wù)器資源有剩余時,可以充分利用剩余的資源提供更多的服務(wù),從而節(jié)約了服務(wù)器資源。

一般有兩種方式來部署MySQL多實例:第一種是使用多個配置文件啟動不同的進(jìn)程來實現(xiàn)多實例,這種方式的優(yōu)勢是邏輯簡單、配置簡單,缺點是管理起來不太方便;第二種是通過官方自帶的mysqld_multi使用單獨的配置文件來實現(xiàn)多實例,這種方式定制每個實例的配置不太方面,優(yōu)點是管理起來很方便,可以集中管理。

mysqld_multi常用的命令如下所示:

●啟動全部實例:mysqld_multistart

●查看全部實例狀態(tài):mysqld_multireport

●啟動單個實例:mysqld_multistart3306。

●停止單個實例:mysqld_multistop3306。

●查看單個實例狀態(tài):mysqld_multireport3306。

13.

什么是前綴索引?正確答案:有時候需要索引很長的字符列,這會讓索引變得大且慢,此時可以考慮前綴索引。MySQL目前還不支持函數(shù)索引,但是支持前綴索引,即對索引字段的前N個字符創(chuàng)建索引,這個特性可以大大縮小索引文件的大小,從而提高索引效率。用戶在設(shè)計表結(jié)構(gòu)的時候也可以對文本列根據(jù)此特性進(jìn)行靈活設(shè)計。前綴索引是一種能使索引更小、更快的有效辦法。

前綴索引的缺點是,在排序ORDERBY和分組GROUPBY操作的時候無法使用,也無法使用前綴索引做覆蓋掃描,并且前綴索引降低了索引的選擇性。索引的選擇性是指不重復(fù)的索引值(也稱為基數(shù),Cardinality)和數(shù)據(jù)表的記錄總數(shù)(COUNT(*))的比值,范圍為(0,1]。索引的選擇性越高則查詢效率越高,因為選擇性高的索引可以讓MySQL在查找時過濾掉更多的行。唯一索引的選擇性是1,這是最好的索引選擇性,性能也是最好的。

一般情況下某個前綴的選擇性也是足夠高的,足以滿足查詢性能。對于BLOB、TEXT,或者很長的、VARCHAR類型的列,必須使用前綴索引,因為MySQL不允許索引這些列的完整長度。

使用前綴索引的訣竅在于要選擇足夠長的前綴以保證較高的選擇性,同時又不能太長(以便節(jié)約空間)。前綴應(yīng)該足夠長,以使得前綴索引的選擇性接近于索引的整個列。換句話說,前綴的“基數(shù)”應(yīng)該接近于完整的列的“基數(shù)”。

為了決定前綴的合適長度,需要找到最常見值的列表,然后和最常見的前綴列表進(jìn)行比較。下面給出一種方法,計算完整列的選擇性,并使其前綴的選擇性接近于完整列的選擇性:

從上面的結(jié)果可以發(fā)現(xiàn)當(dāng)索引前綴為6時的基數(shù)是0.4258,已經(jīng)接近完整列選擇性0.4300。在上面的示例中,已經(jīng)找到了合適的前綴長度,下面創(chuàng)建前綴索引:

mysql>altertablecity_demoaddkey(city(6));

QueryOK,0rowsaffected(0.06sec)

Records:0Duplicates:0Waraings:0

mysql>explainselect*fromcity_demowherecitylike'Jinch%';

從上面結(jié)果可以發(fā)現(xiàn),正確地使用了剛創(chuàng)建的索引。

14.

內(nèi)核線程和用戶線程的區(qū)別?正確答案:根據(jù)操作系統(tǒng)內(nèi)核是否對線程可感知,可以把線程分為內(nèi)核線程和用戶線程。

內(nèi)核線程的建立和銷毀都是由操作系統(tǒng)負(fù)責(zé)、通過系統(tǒng)調(diào)用完成的,操作系統(tǒng)在調(diào)度時,參考各進(jìn)程內(nèi)的線程運行情況做出調(diào)度決定。如果一個進(jìn)程中沒有就緒狀態(tài)的線程,那么這個進(jìn)程也不會被調(diào)度占用CPU資源。

和內(nèi)核線程相對應(yīng)的是用戶線程,用戶線程是指不需要內(nèi)核支持而在用戶程序中實現(xiàn)的線程,其不依賴于操作系統(tǒng)核心,用戶進(jìn)程利用線程庫提供創(chuàng)建、同步、調(diào)度和管理線程的函數(shù)來控制用戶線程。用戶線程多見于一些歷史悠久的操作系統(tǒng),如UNIX操作系統(tǒng),不需要用戶態(tài)/核心態(tài)切換,速度快,操作系統(tǒng)內(nèi)核不知道多線程的存在,因此一個線程阻塞將使得整個進(jìn)程(包括它的所有線程)阻塞。由于這里的處理器時間片分配是以進(jìn)程為基本單位的,所以每個線程執(zhí)行的時間相對減少。為了在操作系統(tǒng)中加入線程支持,采用了在用戶空間增加運行庫來實現(xiàn)線程,這些運行庫被稱為“線程包”,用戶線程是不能被操作系統(tǒng)所感知的。

15.

如何定位執(zhí)行效率較低的SQL語句?正確答案:可以通過以下2種辦法來定位執(zhí)行效率較低的SQL語句:

1)通過慢查詢?nèi)罩径ㄎ弧?梢酝ㄟ^慢查詢?nèi)罩径ㄎ荒切┮呀?jīng)執(zhí)行完畢的SQL語句。

2)使用SHOWPROCESSLIST來查詢。慢查詢?nèi)罩驹诓樵兘Y(jié)束以后才記錄,所以,在應(yīng)用反應(yīng)執(zhí)行效率出現(xiàn)問題的時候查詢慢查詢?nèi)罩静⒉荒芏ㄎ粏栴}。此時,可以使用SHOWPROCESSLIST命令查看當(dāng)前MySQL正在進(jìn)行的線程,包括線程的狀態(tài)、是否鎖表等,可以實時地查看SQL的執(zhí)行情況,同時對一些鎖表操作進(jìn)行優(yōu)化。

找到執(zhí)行效率低的SQL語句后,就可以通過“SHOWPROFILEFORQUERYN”、EXPLAIN或trace等方法來優(yōu)化這些SOL語句。

16.

MySQL中索引的使用原則有哪些?正確答案:索引的設(shè)計可以遵循一些已有的原則,創(chuàng)建索引的時候請盡量考慮符合這些原則,便于提高索引的使用效率,更高效地使用索引。

1)最適合索引的列是出現(xiàn)在WHERE子句中的列,或連接子句中指定的列,而不是出現(xiàn)在SELECT關(guān)鍵字后的選擇列表中的列。

2)使用唯一索引。考慮某列中值的分布。索引的列的基數(shù)越大,索引的效果越好。唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。例如,學(xué)生表中的學(xué)號是具有唯一性的字段。為該字段建立唯一性索引可以很快的確定某個學(xué)生的信息。如果使用姓名的話,可能存在同名現(xiàn)象,從而降低查詢速度。

3)使用短索引。如果對字符串列進(jìn)行索引,那么應(yīng)該指定一個前綴長度。例如,有一個CHAR(200)列,如果在前10個字符內(nèi),大多數(shù)值是唯一的,那么就不要對整個列使用索引。對前10個字符進(jìn)行索引能夠節(jié)省大量索引空間,也會使查詢更快,因為較小的索引涉及的磁盤I/O較少,較短的值比較起來更快。更為重要的是,對于較短的鍵值,索引高速緩存中的塊能容納更多的鍵值,因此,MySQL也可以在內(nèi)存中容納更多的值。

4)利用最左前綴。在創(chuàng)建一個n列的索引時,實際是創(chuàng)建了MySQL可利用的n個索引。多列索引可以起到多個索引的作用,因為可利用索引中最左邊的列集來匹配行。這樣的列集被稱為最左前綴(LeftmostPrefixing)。

5)不要過度索引。不要以為索引“越多越好”,什么東西都用索引是錯誤的。因為每個索引都要占用額外的磁盤空間,并降低寫操作的性能,增加維護(hù)成本。在修改表的內(nèi)容時,索引必須進(jìn)行更新,有時也可能需要重構(gòu),因此,索引越多,維護(hù)索引所花的時問也就越長。如果有一個索引很少利用或從不使用,那么會不必要地減緩表的修改速度。此外,MySQL在生成一個執(zhí)行計劃時,要考慮各個索引,這也要花費時間。創(chuàng)建多余的索引給查詢優(yōu)化帶來了更多的工作。索引太多,也可能會使MySQL選擇不到所要使用的最好索引。只保持所需的索引有利于查詢優(yōu)化。

6)對于InnoDB存儲引擎的表,記錄默認(rèn)按照一定的順序保存,如果有明確定義的主鍵,那么按照主鍵順序保存。如果沒有主鍵,但是有唯一索引,那么就是按照唯一索引的順序保存。如果既沒有主鍵又沒有唯一索引,那么表中會自動生成一個內(nèi)部列,按照這個列的順序保存。按照主鍵或者內(nèi)部列進(jìn)行的訪問是最快的,所以InnoDB表盡量自己指定主鍵,當(dāng)表中同時有幾個列都是唯一的,都可以作為主鍵的時候,要選擇最常作為訪問條件的列作為主鍵,提高查詢的效率。另外,還需要注意,InnoDB表的普通索引都會保存主鍵的鍵值,所以主鍵要盡可能選擇較短的數(shù)據(jù)類型,可以有效地減少索引的磁盤占用,提高索引的緩存效果。

7)為經(jīng)常需要排序、分組和聯(lián)合操作的字段建立索引。經(jīng)常需要ORDERBY、GROUPBY、DISTINCT和UNION等操作的字段,排序操作會浪費很多時間。如果為其建立索引,可以有效地避免排序操作。

8)盡量使用數(shù)據(jù)量少的索引。如果索引的值很長,那么查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進(jìn)行全文檢索需要的時間肯定要比對CHAR(10)類型的字段進(jìn)行檢索需要的時間要多。

9)盡量使用前綴來索引。如果索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進(jìn)行全文檢索會很浪費時間。如果只檢索字段的前面的若干個字符,這樣可以提高檢索速度。

10)刪除不再使用或者很少使用的索引。表中的數(shù)據(jù)被大量更新,或者數(shù)據(jù)的使用方式被改變后,原有的一些索引可能不再需要。數(shù)據(jù)庫管理員應(yīng)當(dāng)定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。

需要注意的是:選擇索引的最終目的是為了使查詢的速度變快。上面給出的原則是最基本的準(zhǔn)則,但不能拘泥于上面的準(zhǔn)則。讀者要在以后的學(xué)習(xí)和工作中進(jìn)行不斷的實踐。根據(jù)應(yīng)用的實際情況進(jìn)行分析和判斷,選擇最合適的索引方式。

17.

什么是MySQL的套接字文件?正確答案:MySQL有兩種連接方式,常用的是TCP/IP方式,如下所示:

[root@LHRDB~]#mysql-h59-uroot-plhr

mysql:[Warning]Usingapasswordonthecommandlineinterfacecanbeinsecure.

WelcometotheMySQLmonitor.Commandsendwith;or\g.

YourMySQLconnectionidis9

Serverversion:5.7.19MySQLCommunityServer(GPL)

Copyright(c)2000,2017,Oracleand/oritsaffiliates.Allrightsreserved

OracleisaregisteredtrademarkofOracleCorporationand/orits

affiliates.Othernamesmaybetrademarksoftheirrespective

owners.

Type'help;'or'\h'forhelp.Type'\c'toclearthecurrentinputstatement.

mysql>

還有一種是套接字方式。Unix系統(tǒng)下本地連接MySQL可以采用Unix套接字方式,這種方式需要一個套接字(Socket)文件。套接字文件就是當(dāng)用套接字方式進(jìn)行連接時需要的文件。套接字方式比用TCP/IP的方式更快、更安全,但只適用于MySQL和客戶端在同一臺PC上的場景。套接字文件可由參數(shù)socket控制,一般在/tmp目錄下,名為mysql.sock,也可以放在其他目錄下,如下所示:

用套接字連接MySQL:

[root@LHRDB~]#mysql-S/tmp/mysqld.sock

ERROR2002(HY000):Can'tconnecttolocalMySQLserverthroughsocket'/tmp/mysqldsock'(2)

[root@LHRDB~]#mysql-plhr-S/var/lib/mysql57/mysql.sock

mysql:[Warning]Usingapasswordonthecommandtineinterfacecanbeinsecure.

WelcometotheMySQLmonitor.Commandsendwith;or\g.

YourMySQLconnectionidis8

Serverversion:5.7.19MySQLCommtmityServer(GPL)

Copyright(c)2000,2017,Oracleand/oritsaffiliates.Allrightsreserved.

OracleisaregisteredtrademarkofOracleCorporationmad/orits

affiliates.Othernamesmaybetrademarksoftheirrespective

owners.

Type'help;'or'\h'forhelp.Type'\c't

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論