關系數據庫的世界是一個表與集合、表與集合上的運算占統治地位的世界。數據庫是一個表的集合,而表又是行和列的集合。在發布一條SELECT 查詢從表中進行檢索行時,得到另一個行和列的集合。這些都是一些抽象的概念,對於數據庫系統用來操縱表中數據的基本表示沒有多少參考價值。另一個抽象概念是,表上的運算都同時進行;查詢是一種概念性的集合運算,並且集合論中沒有時間概念。當然,現實世界是相當不同的。數據庫管理系統實現了抽象的概念,但是在實際的硬件范圍內要受到實際的物理約束。結果是,查詢要花時間,有時要花很長的時間。而人類很容易不耐煩,不喜歡等待,因此我們丟下了集合上的那些瞬間的數學運算的抽象世界去尋求加速查詢的方法。幸運的是,有幾種加速運算的技術,可對表進行索引使數據庫服務器查找行更快。可考慮怎樣充分利用這些索引來編寫查詢。可編寫影響服務器調度機制的查詢,使來自多個客戶機的查詢協作得更好。我們思考基本硬件怎樣運行,以便想出怎樣克服其物理約束對性能進行改善的方法。
這些正是本章所要討論的問題,其目標是優化數據庫系統的性能,使其盡可能快地處理各種查詢。MySQL 已經相當快了,但即使是最快的數據庫,在人的設計下還能運行得更快。
4.1 使用索引
我們首先討論索引,因為它是加快查詢的最重要的工具。還有其他加快查詢的技術,但是最有效的莫過於恰當地使用索引了。在MySQL 的郵件清單上,人們通常詢問關於使查詢更快的問題。在大量的案例中,都是因為表上沒有索引,一般只要加上索引就可以立即解決問題。但這樣也並非總是有效,因為優化並非總是那樣簡單。然而,如果不使用索引,在許多情形下,用其他手段改善性能只會是浪費時間。應該首先考慮使用索引取得最大的性能改善,然後再尋求其他可能有幫助的技術。
本節介紹索引是什麼、它怎樣改善查詢性能、索引在什麼情況下可能會降低性能,以及怎樣為表選擇索引。下一節,我們將討論MySQL 的查詢優化程序。除了知道怎樣創建索引外,了解一些優化程序的知識也是有好處的,因為這樣可以更好地利用所創建的索引。某些編寫查詢的方法實際上會妨礙索引的效果,應該避免這種情況出現。(雖然並非總會這樣。有時也會希望忽略優化程序的作用。我們也將介紹這些情況。)
4.1.1 索引的益處
讓我們從一個無索引的表著手來考察索引是怎樣起作用的。無索引的表就是一個無序的行集。例如,圖4 - 1給出了我們在第1章“MySQL 與SQL 介紹” 中首先看到的ad 表。這個表上沒有索引,因此如果我們查找某個特定公司的行時,必須查看表中的每一行,看它是否與所需的值匹配。這是一個全表掃描,很慢,如果表中只有少數幾個記錄與搜索條件相匹配,則其效率是相當低的。