程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mysql 索引的基礎(下),mysql索引基礎

Mysql 索引的基礎(下),mysql索引基礎

編輯:MySQL綜合教程

Mysql 索引的基礎(下),mysql索引基礎


  如果需要存儲大量的URL並需要根據URL進行搜索查找。如果使用B-Tree 來存儲URL,存儲的內容就會很大,因為URL本身都很長。正常情況下會有如下查詢:

SELECT id FROM url WHERE url="http://www.baidu.com";

  若刪除原來URL上的索引,而新增一個被索引的url_crc列,使用CRC32做hash ,就可以用下面的方式查詢:

SELECT id FROM url WHERE url='http://www.baidu.com' AND rul_crc=CRC32('http://www.baidu.com');

  這樣做性能非常高,因為MySQL 優化器會使用這個選擇性很高而體積很小的基於url_crc列的索引來完成查找。即使有多個相同的索引值,查找任然很快,只需要根據hash值做快速的整數比較就能找到索引條目,然後一一返回對應的行。另外一種方式就是對完整的URL字符串做索引,那樣會非常慢。

  這樣實現的缺陷是需要維護hash值。可以手動維護,可以觸發器實現。如果采用這種方式,記住,不要使用SHA1()和MD5()作為哈希函數。因為這兩個函數計算出來的hash值時非常長的字符串,會浪費更大的空間,比較時也會更慢。SHA1()和MD5()是強加密函數,設計目標是最大限度的消除沖突,蛋這裡並不需要這樣搞的要求。簡單hash函數的沖突在一個可以接受的范圍,同事有能提供更好的性能。

  如果數據表非常大,CRC32()會出現大量的hash沖突,則可以考慮自己實現一個簡單的64位hash函數。這個自定義的函數要返回整數,而不是字符串。一個簡單的辦法可以使用MD5()函數返回值的一部分來作為自定義hash函數。這肯能比自己寫一個hash算法的性能要差,不過這樣實現最簡單。

  SELECT CONV(RIGHT(MD5('http://www.baidu.com'),16),16,10) AS HASH64.

  處理hash沖突。當使用hash索引進行查詢的時候,必須在WHERE子句中包含常量值:

  SELECT id from url WHERE url=crc32('http://www.baidu.com') AND url='http://www.baidu.com';

  一旦出現hash沖突,另一個字符串的hash值也恰好是相同的,則下面的語句是無法正確工作的:

  SELECT id from url WHERE url=crc32('http://www.baidu.com');

  因為所謂的‘生日悖論’ 出現hash沖突的概率的增長率可能比想象的要快的多,CRC32()返回的是32位整數,當索引有9.3W條記錄時,出現沖突的概率是1%。例如,我們將'/usr/share/dic/words' 中的詞倒數數據表,並進行crc32()計算,最後會有98569行。這就已經出現一次hash沖突了。要避免hash沖突問題,必須在WHERE 條件中帶入hahs值和對應的列值。如果不是想查詢具體的值,例如只是統計記錄數(不精確的),則可以不帶入列值,直接使用crc32()的hash值查詢即可。還可以使用FNV64()函數作為hash函數,hash值為64位,速度非常快,且沖突比crc32()要少很多。

  

 

 

 

  

 

 

 

    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved