php - 选择使用长变量与 MD5 性能明智

标签 php mysql select md5

假设我有一个包含长变量(URL,例如 100-250 个字符)的大表(超过 100000 个条目)。将 MD5 散列作为旁边的单独字段以从表中获取单行是否对提高性能有意义?

SELECT * FROM `urls` WHERE `url` = 'http://long-phrase...' LIMIT 1;

SELECT * FROM `urls` WHERE `url_md5` = MD5('http://long-phrase...') LIMIT 1;

最佳答案

我想使用 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 万行。

另一方面,如果您只能搜索有序的行列表,那将是 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 万行才能找到您的 url(“它不在此处”)。
  • 平均 50 万行(“平均分配”)。
  • log2(10^6) == 20 在最坏的情况下检查 INDEX 中的 url。
  • log2(10^6)-1 == 19 平均检查 INDEX 中的 url。

明天你将有 200 万行。现在您必须通过不使用 INDEX 扫描超过 200 万行,并且您将不得不扫描最多 20 次才能找到正确的记录或什么也找不到。数百万次字符串比较与 20 次比较。您会看到使用 INDEX 的影响有多大。

在此处阅读有关该主题的更多信息:

关于php - 选择使用长变量与 MD5 性能明智,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14402763/

相关文章:

php - 在表单类型中使用 Symfony2 UserPassword 验证器

php - 在单个数组中返回多个 SELECT 查询

c - 在循环和多个操作中使用选择系统调用

php - 如何在图表中显示每天的总订单金额

php - 如何检测 PHP/MySQL 是否经过了一定的时间?

java - 如何连接桌面 java 应用程序和在线 mysql 数据库并执行查询?

php - MySQL查询: selecting latest results

php - 选择在包含多个以逗号分隔的 id 的列中搜索某个 id 的行

php - WSO2 WSF PHP - WSClientProxy -> __调用没有返回大响应

python - DateTimeField 收到一个天真的日期时间