我猜使用 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。因此,假设数据库现在存储了在您插入行时未排序但按“url”字段排序的行。现在,只要您插入新行,数据库就必须重新排序磁盘上所有存储的字节。因为,您现在可以更快地搜索,但 INSERT 操作要慢得多。并且不要忘记:明天您要搜索“descr”字段。现在怎么办?重新排序整个文件?保留文件的 2 个副本?
更好的方法是使用寄存器,一个有序列表,其中包含在何处找到“行”的参考。这个想法与现实世界的图书馆一样古老:只需将书籍一个接一个地放在书架上,给它编号,然后创建列表:一个按作者姓名排序,一个按出版年份排序,一个按标题等。想要搜索作者 选择作者注册,通过类似二分搜索的方法扫描名称(如果此人很聪明),获取书号,上书架并快速拿起书.
那个“注册”的东西也被称为“索引”:磁盘上引用行位置的有序引用列表:
[s:35:http://...s:9:somewhere...][s:45:http://...s:9:wherever...][...]
^ ^ ^
| | |
| | |
i1 -------------------------------- ^ |
i2 ------------------------------------------------------------------>
i3 -^ |
i100 -------------------------------------------------------------^
例如,您现在可以检查 i50 以查看您的搜索词是否匹配。如果索引函数指向大于 50 的值,则在下一轮检查 i75,如果小于 50,则检查 i25,依此类推。
给你数字:给定 100 万行,你搜索“url”字段,你必须扫描:
- 在最坏的情况下需要 100 万行来找到您的网址(“它不在此处”)。
- 平均 50 万行(“平均分布”)。
- log2(10^6) == 20 在最坏的情况下检查 INDEX 中的 url。
- log2(10^6)-1 == 19 次平均检查 INDEX 中的 url。
明天你将有 200 万行。现在您必须不使用 INDEX 扫描超过 200 万行,并且您必须最多扫描 20 次才能找到正确的记录或什么也没有。数百万次字符串比较与 20 次比较。您会看到使用 INDEX 的影响有多大。
在此处阅读有关该主题的更多信息: