資料庫管理系統實現了理論上的概念,但是這種在實際硬體裝置上的實現受到了實際物理條件的約束。其結果是,查詢需要花費一些時間--有時候需要很長的時間。本期專題的內容就是幫助你找到如何讓自己的等待時間最短的方法。
1、 使用索引
索引是提高查詢速度的最重要的工具。當然還有其它的一些技術可供使用,但是一般來說引起最大效能差異的都是索引的正確使用。因此我首先講述是什麼索引以及索引是怎麼樣提高查詢效能的。同時還要討論在某些環境中索引可能降低效能,並選擇提供了資料表的索引一些指導方針。
索引是提高查詢速度的最重要的工具。當然還有其它的一些技術可供使用,但是一般來說引起最大效能差異的都是索引的正確使用。在mysql郵件列表中,人們經常詢問那些讓查詢執行得更快的方法。在大多數情況下,我們應該懷疑資料表上有沒有索引,並且通常在新增索引之後立即解決了問題。當然,並不總是這樣簡單就可以解決問題的,因為優化技術本來就並非總是簡單的。然而,如果沒有使用索引,在很多情況下,你試圖使用其它的方法來提高效能都是在浪費時間。首先使用索引來獲取最大的效能提高,接著再看其它的技術是否有用。
這一部分講述了索引是什麼以及索引是怎麼樣提高查詢效能的。它還討論了在某些環境中索引可能降低效能,並為你明智地選擇資料表的索引提供了一些指導方針。在下一部分中我們將討論mysql查詢優化器,它試圖找到執行查詢的效率最高的方法。了解一些優化器的知識,作為對如何建立索引的補充,對我們是有好處的,因為這樣你才能更好地利用自己所建立的索引。某些編寫查詢的方法實際上讓索引不起作用,在一般情況下你應該避免這種情形的發生。 索引的優點 讓我們開始了解索引是如何工作的,首先有乙個不帶索引的資料表。不帶索引的表僅僅是乙個無序的資料行集合。例如,圖1顯示的ad表就是不帶索引的表,因此如果需要查詢某個特定的公司,就必須檢查表中的每個資料行看它是否與目標值相匹配。這會導致一次完全的資料表掃瞄,這個過程會很慢,如果這個表很大,但是只包含少量的符合條件的記錄,那麼效率會非常低。圖1
圖2是同樣的一張資料表,但是增加了對ad表的company_num資料列的索引。這個索引包含了ad表中的每個資料行的條目,但是索引的條目是按照company_num值排序的。現在,我們不是逐行檢視以搜尋匹配的資料項,而是使用索引。假設我們查詢公司13的所有資料行。我們開始掃瞄索引並找到了該公司的三個值。接著我們碰到了公司14的索引值,它比我們正在搜尋的值大。索引值是排過序的,因此當我們讀取了包含14的索引記錄的時候,我們就知道再也不會有更多的匹配記錄,可以結束查詢操作了。因此使用索引獲得的功效是:我們找到了匹配的資料行在哪兒終止,並能夠忽略其它的資料行。另乙個功效來自使用定位演算法查詢第一條匹配的條目,而不需要從索引頭開始執行線性掃瞄(例如,二分搜尋就比線性掃瞄要快一些)。通過使用這種方法,我們可以快速地定位第乙個匹配的值,節省了大量的搜尋時間。資料庫使用了多種技術來快速地定位索引值,但是在本文中我們不關心這些技術。重點是它們能夠實現,並且索引是個好東西。
你可能要問,我們為什麼不對資料行進行排序從而省掉索引?這樣不是也能實現同樣的搜尋速度的改善嗎?是的,如果表只有乙個索引,這樣做也可能達到相同的效果。但是你可能新增第二個索引,那麼就無法一次使用兩種不同方法對資料行進行排序了(例如,你可能希望在顧客名稱上建立乙個索引,在顧客id號或**號碼上建立另外乙個索引)。把與資料行相分離的條目作為索引解決了這個問題,允許我們建立多個索引。此外,索引中的行一般也比資料行短一些。當你插入或刪除新的值的時候,移動較短的索引值比移動較長資料行的排序次序更加容易。 不同的mysql儲存引擎的索引實現的具體細節資訊是不同的。例如,對於myisam資料表,該錶的資料行儲存在乙個資料檔案中,索引值儲存在索引檔案中。乙個資料表上可能有多個索引,但是它們都被儲存在同乙個索引檔案中。索引檔案中的每個索引都包含乙個排序的鍵記錄(它用於快速地訪問資料檔案)陣列。 與此形成對照的是,bdb和innodb儲存引擎沒有使用這種方法來分離資料行和索引值,儘管它們也把索引作為排序後的值集合進行操作。在預設情況下,bdb引擎使用單個檔案儲存資料和索引值。innodb使用單個資料表空間(tablespace),在表空間中管理所有innodb表的資料和索引儲存。我們可以把innodb配置為每個表都在自己的表空間中建立,但是即使是這樣,資料表的資料和索引也儲存在同乙個表空間檔案中。前面的討論描述了單個表查詢環境下的索引的優點,在這種情況下,通過減少對整個表的掃瞄,使用索引明顯地提高了搜尋的速度。當你執行涉及多表聯結(jion)查詢的時候,索引的價值就更高了。在單錶查詢中,你需要在每個資料列上檢查的值的數量是表中資料行的數量。在多表查詢中,這個數量可能大幅度上公升,因為這個數量是這些表中資料行的數量所產生的。 假設你擁有三個未索引的表t1、t2和t3,每個表都分別包含資料列i1、i2和i3,並且每個表都包含了1000條資料行,其序號從1到1000。查詢某些值匹配的資料行組合的查詢可能如下所示:
select t1.i1, t2.i2, t3.i3
from t1, t2, t3
where t1.i1 = t2.i2 and t2.i1 = t3.i3;
from
tbl1 leftjoin tbl2
on tbl1.col_b = tbl2.col_c
where col_d = expr;
mysql何時使用索引
對乙個鍵碼使用》, >=, =,
select * from table_name where key_part1=1 and key_part2 > 5;
select * from table_name where key_part1 is null;
當使用不以萬用字元開始的like
select * from table_name where key_part1 like 'jani%'
在進行聯結時從另乙個表中提取行時
select * from t1,t2 where t1.col=t2.key_part
找出指定索引的max()或min()值
select min(key_part2),max(key_part2) from table_name where key_part1=10
乙個鍵碼的字首使用order by或group by
select * from foo order by key_part1,key_part2,key_part3
在所有用在查詢中的列是鍵碼的一部分時間
select key_part3 from table_name where key_part1=1
mysql何時不使用索引
如果mysql能估計出它將可能比掃瞄整張表還要快時,則不使用索引。例如如果key_part1均勻分布在1和100之間,下列查詢中使用索引就不是很好:
select * from table_name where key_part1 > 1 and key_part1 < 90
如果使用heap表且不用=搜尋所有鍵碼部分。
在heap表上使用order by。
如果不是用鍵碼第一部分
select * from table_name where key_part2=1
如果使用以乙個萬用字元開始的like
select * from table_name where key_part1 like '%jani%'
搜尋乙個索引而在另乙個索引上做order by
select * from table_name where key_part1 = # order by key2
2、mysql查詢優化器
了解一些優化器的知識,作為對如何建立索引的補充,對我們是有好處的,因為這樣你才能更好地利用自己所建立的索引。某些編寫查詢的方法實際上讓索引不起作用,在一般情況下你應該避免這種情形的發生。這一講中將討論mysql查詢優化器,我將試圖找到執行具有最高效率查詢的方法。
3、資料型別與效率
在大多數情況下,你所關注的是select查詢的優化,因為select查詢是最常見的查詢型別,而且如何優化它們又不是太簡單。與此形成對比,把資料載入資料庫的操作就相對直接了。然而,你仍然可以利用某些策略來改善資料載入操作的效率。
4、排程和鎖定的問題
前面的部分主要是聚焦於如何讓單獨的查詢執行的速度更快。mysql還允許你改變語句排程的優先順序,它可以使來自多個客戶端的查詢更好地協作。改變優先順序還可以確保特定型別的查詢被處理得更快。這一部分講解mysql的預設的排程策略和可以用來影響這些策略的選項。它還談到了併發性插入操作的使用和儲存引擎鎖定層次對客戶端的併發性的影響。
5、管理員的優化措施
前面的部分中講解的優化措施都是沒有特權的mysql使用者能夠執行的。可以控制mysql伺服器或計算機的系統管理員能夠執行額外的優化措施。
索引對查詢效率的影響
我們將利用advanturewords2008r2中的sales.salesorderdetail表,其中有12萬條資料,非常適合用於測試。不過我們不直接在這張表上做測試,因為這張表上已經有索引了。我們需要新建一張表,將該表中的資料匯入我們新建的test和test2表。test和test2的建立方法...
std map查詢效率優化
0.現狀,資料是個xml檔案,每個節點對應的結構體有10個成員變數,共有2000多條資料,用的std map來儲存,用map的find函式進行搜尋時的效率極 其低下,迴圈搜尋30條資料竟然要20s 搓死。1.為什麼這麼慢?最初懷疑是std map的效率問題,正考慮是否使用std hast map來替...
優化sql,避免影響sql的執行效率
1.避免使用 select from 表名 只查詢需要的需要的字段 如果表字段較多,用到的字段佔表字段中的少數,使用select 造成資源浪費,影響sql執行效率 但是如果查詢的表字段較少,或者表中80 資料字段都是需要用到的,可以使用select from 表名 2.限制結果集的資料量。查詢時不要...