資料庫索引問題

來源:互聯網
上載者:User

 

遇到的問題前提如下:

一張包含四個欄位的表,表名為test,表中有100萬條記錄。

        第一列為id,主鍵,自增。

        第二列為col1,隨機為Mike,Bob,Jack,Alice,Cathy,Ann,Betty,Cindy,Mary,Jane中的一個

        第三列為col2,隨機為一個5位字母,字母限制在a-e

        第三列為col3,隨機為一個1-20之間的整數

 

(1)select count(*) from test group by col1 order by count(*);記錄執行時間

(2)找出所有第二列以ab開頭的記錄,記錄執行時間

 

對於第一題建立col1上的索引以後查詢時間縮短了一半。而第二題建立在col2上的索引發現時間由原來的0.6s增加到7s。

我的環境是java語言和mysql資料庫,使用jdbc串連。

下面是第二題添加索引代碼和查詢的代碼

public static void dropCol1Index() {<br />try {<br />Statement st = conn.createStatement();<br />String sql = "drop index test_col1 on test;";<br />st.execute(sql);<br />st.close();<br />System.out.println("col1Index has been deleted");<br />System.out.println();<br />} catch (Exception e) {<br />e.printStackTrace();<br />}<br />}<br />public static void query2() {<br />try {<br />System.out<br />.println("start query2: 'select * from test where col2 > /'ab/' and col2 </'ac/';'");<br />Long beginTime = System.currentTimeMillis();<br />Statement st = conn.createStatement();<br />String sql = "select * from test where col2 > /'ab/' and col2 </'ac/';";<br />ResultSet rs = st.executeQuery(sql);<br />Long endTime = System.currentTimeMillis();<br />// System.out.println("result:");<br />// while (rs.next()) {<br />// System.out.print(rs.getInt(1)+" ");<br />// System.out.print(rs.getString(2)+" ");<br />// System.out.print(rs.getString(3)+" ");<br />// System.out.println(rs.getInt(4));<br />// }<br />System.out.println("query2 time: " + (double) (endTime - beginTime)<br />/ 1000 + " s");<br />System.out.println();<br />st.close();<br />} catch (Exception e) {<br />e.printStackTrace();<br />}<br />}

 

得到高人指點,將該疑惑解決了。

 

我嘗試著在插入col2的資料時,有規律的插入資料,因為總行數為100萬行,資料範圍從aaaaa到eeeee一共有3125種,可以按照順序將每種資料插入320行,這樣整體col2的資料就是根據字典序進行排序的。同樣建立索引以後查詢,用時在0.2s左右。終於恍然大悟。

 

從網上看到相關資料,瞭解到當col2是隨機值時,在col2上建立的索引屬於非叢集索引(非叢集索引就好像按照偏旁部首的索引方式尋找漢語字典中的字),而當col2是按照一定的順序存放時,在col2上建立的索引屬於叢集索引(叢集索引就好像按照漢語拼音的索引方式尋找漢語字典中的字)。在實際應用中,叢集索引可以高效的提高查詢速度,而非叢集索引則不具有這個特性。

 

具體的原因可能是這樣的,對於聚集資料,當使用者查詢時,通過索引尋找到資料在磁碟中的位置,因為其的聚集特性,可以從這個位置開始順序的讀取大量的符合要求的資訊。就好像你以漢語拼音為索引尋找一個讀音的頁碼以後,可以找到大量的這個讀音的字。但是非聚集則不然,非叢集索引查詢到的結果分布在磁碟的各個地方,需要頻繁的移動磁頭才能夠擷取這些資訊,就好像你以偏旁部首為索引尋找一個偏旁部首的字時,你要頻繁的翻動書頁才能找到所有的符合要求的字。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.