假设我有一个包含长变量的大表(100000多个条目)(URL,如100-250个字符)。为了获得更好的性能,将MD5哈希作为其旁边的单独字段从表中获取单行是否有意义?
SELECT * FROM `urls` WHERE `url` = 'http://long-phrase...' LIMIT 1;
OR
SELECT * FROM `urls` WHERE `url_md5` = MD5('http://long-phrase...') LIMIT 1;
答案 0 :(得分:2)
我猜想使用INDEX就足够了,这就是为什么,在一个下雪的星期天用平淡无奇的心情写的:
数据库将其行一个接一个地存储在文件中:
id url name descr visited
1 http://... somewhere i like it 2013-01-01
2 http://... wherever i dislike it 2013-01-02
...
您将在磁盘上大致如下所示:
[s:35:http://...s:9:somewhere...][s:45:http://...s:9:wherever...][...]
一堆字节,很多字节。如果您要求数据库搜索给定的术语,则数据库必须通过扫描文件来扫描“行”并应用搜索项。假设您有100万行,数据库必须扫描100万行。假设您要在行中搜索“url”字段。让我们说你更容易“搜索”,因为你缩短了(或扩展,做了“http://goo.gl/P0Gwz”的md5)字符串:你仍然需要搜索100万行。
另一方面,如果你只是搜索一个ORDERED行列表,那就是really speed things up。因此,假设DB现在存储了在您插入行但未按“url”-field排序时排序的行。现在,只要您插入新行,数据库就必须重新排序磁盘上所有存储的字节。对于coz,您现在能够更快地搜索,但INSERT操作要慢得多。不要忘记:明天你想搜索“descr”-field。现在怎么办?重新排序整个文件?保留2份文件?
更好的方法是使用寄存器,有序列表以及在哪里找到“行”。这个想法与真实世界的图书馆一样古老:只需将书籍一个接一个地放入书架,编号并创建列表:一个按作者名称排序,一个按出版年份排序,一个按标题排序等。任何给定的人想要搜索作者选择作者注册,通过类似二元搜索的方法扫描名称(如果这个人很聪明),获取书籍的数量,上架并快速拿起书
“register”thingy也称为“INDEX”:磁盘上引用行位置的引用的有序列表:
[s:35:http://...s:9:somewhere...][s:45:http://...s:9:wherever...][...]
^ ^ ^
| | |
| | |
i1 -------------------------------- ^ |
i2 ------------------------------------------------------------------>
i3 -^ |
i100 -------------------------------------------------------------^
例如,您现在可以查看i50
以查看您的搜索字词是否匹配。如果index-function指向大于50的东西你在下一轮检查i75,如果它小于50你检查i25,依此类推。
为您提供数字:给定100万行,并搜索“url”字段,您必须扫描:
明天你将有200万行。现在你必须通过不使用INDEX来扫描超过200万行,你必须扫描~20次最大值才能找到正确的记录或什么都没有。数百万次字符串比较与20次。您会看到使用INDEX会产生多大影响。
点击此处了解有关该主题的更多信息: