有的时候你可能需要索引字符数非常多的列。这会让你的索引非常大并且很慢。一个策略就是模拟hash索引。前一部分已经说过了。但是有的时候这种方法也不是很好。将要怎么做。
一般可以用索引前一部分的一些字符的方法来节省空间并且可以获得好的性能。这样可以使你的索引使用更少的空间,但是这样会降低选择性。索引的选择性(Index selectivity)是索引值的数量和表中行的数量(#T)的一个比率。范围是1/#T到1.索引的选择性越高越好,因为这样当匹配的时候,MySQL就会过滤掉更多的行。一个唯一索引的选择性1,这是最好的了。
一个前缀的索引对于好的性能来说,它的选择性已经足够了。如果你对BLOB和TEXT列进行索引,或者非常长的VARCHAR列,你必须定义前缀索引,因为MySQL不允许索引它们的全部长度。
技巧就是选择一个列的前缀,并且这个前缀的长度能有个好的选择性,但是又可能节约更多的空间。索引前缀所带来的索引效果应该尽可能的接近索引全部长度所带来的效果。
要知道一个好的前缀的长度,找到最常见的值并且把它们和最常见的前缀进行比较。看下如下例子
CREATE TABLE sakila.city_demo(city VARCHAR(50) NOT NULL);
INSERT INTO sakila.city_demo(city) SELECT city FROM sakila.city;
-- Repeat the next statement five times:
INSERT INTO sakila.city_demo(city) SELECT city FROM sakila.city_demo;
-- Now randomize the distribution (inefficiently but conveniently):
UPDATE sakila.city_demo
SET city = (SELECT city FROM sakila.city ORDER BY RAND( ) LIMIT 1);
现在我们有一个示例数据集。结果并不是真是分布的,并且我们使用了RAND(),因此结果是变化的,但是对于此练习并不会有什么影响。首先我们找到出现频率最高的cities.
mysql> SELECT COUNT(*) AS cnt, city
-> FROM sakila.city_demo GROUP BY city ORDER BY cnt DESC LIMIT 10;
发现每个城市出现的次数范围为45-65.现在我们在查找频率出现最高的前缀。从3个字母的前缀开始。
+-----+------+
| cnt | pref |
+-----+------+
| 483 | San |
| 195 | Cha |
| 177 | Tan |
| 167 | Sou |
| 163 | al- |
| 163 | Sal |
| 146 | Shi |
| 136 | Hal |
| 130 | Val |
| 129 | Bat |
+-----+------+
每个前缀都出现了很多次。因此有太多的唯一前缀要多于唯一全长度的city names.接下来的方法就是提高前缀的长度直到这个前缀的选择性接近于全长度的列。通过实验发现前缀长度为7最为合适。
mysql> SELECT COUNT(*) AS cnt, LEFT(city, 7) AS pref
-> FROM sakila.city_demo GROUP BY pref ORDER BY cnt DESC LIMIT 10;
+-----+---------+
| cnt | pref |
+-----+---------+
| 70 | Santiag |
| 68 | San Fel |
| 65 | London |
| 61 | Valle d |
| 49 | Hiroshi |
| 48 | Teboksa |
| 48 | Pak Kre |
| 48 | Yaound |
| 47 | Tel Avi |
| 47 | Shimoga |
+-----+---------+ (编辑:滁州站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|