我正在寻找最快/最有效的方法来搜索数千万个用户名中是否有给定的用户名。目前,我正在使用运行每个按键的普通MySQL SELECT查询,但是我对性能不满意。我正在使用索引,分区等,我知道MySQL可以优化得非常快,但是我也知道有更好的解决方案。
那么最快的用户名搜索是什么
例如:Gmail在注册时如何在数十亿个电子邮件地址中进行搜索。 Facebook是如何做到的?我以为他们不只是运行SQL查询。
我正在寻找适用于PHP应用程序的实用解决方案。
现在我只是使用一个非常基本的选择:
SELECT username FROM users WHERE username = $username LIMIT 1
用户名列具有唯一索引
答案 0 :(得分:3)
我同意您应该将其全部粘贴到RAM中(例如Redis)。
但是,如果您不想一路走下去,请执行以下操作:将列表存储在较慢的位置(例如S3或SQL数据库)。接下来,从该列表中创建一个Bloom过滤器(在Wikipedia上有东西,并且有一个漂亮的Redis模块,您可以使用-https://oss.redislabs.com/redisbloom)。
现在,BF告诉您永远不会给您带来误报,因此您可以有效地检查用户名是否可用。但是,有时BF会报告用户名不可用(误报),您已决定是否可以使用该用户名。
答案 1 :(得分:0)
将列表加载到关联数组中。测试密钥的存在。做完了如今,“数百万”的数据并不多。它适合RAM。
如果您的内存不足并且不介意天文学上出现误报的可能性很小,则可以使用SHA2-256哈希值代替完整值。这些只是40字节的十六进制编码,原始格式为20字节。在许多情况下,甚至甚至 O(1)时间,检查哈希键是否已编入索引都是很简单的。
请记住,只有当您处理的峰值负载超过每秒1000个查询时,这才有意义。不要过早地对此进行优化。大多数数据库基本上可以在零时间内进行用户名测试,这甚至不难,而且每秒进行一千次测试不会破坏您的服务器。
如果您确实有一个可衡量的性能问题,那么您随时可以探索索引选项。 MySQL supports different index types:BTREE
或HASH
。它们的表现不同。
答案 2 :(得分:0)
您的示例中提到了使用高端系统的公司。显然,没有任何系统可以做到这一点,这就是原因:
让我们假设一个巨大的公司如何处理数十亿用户名:
有一种服务,可能是用C编写的,甚至不是用C ++编写的。
它部署在Unix或Linux集群上
还有一个服务充当第一个服务的健康检查程序,该服务检查每个其次是标准的用户名和密码
该服务将所有数据(通常是用户名和密码)加载到内存中
当数据在源处发生更改时,它被称为采用更改,这是从数据源触发的
当需要对数据进行调用(我们的情况)时,对主服务处于活动状态的运行状况检查程序的两个副本进行2(最少)异步调用(以避免服务中断延迟)
当任何健康检查程序均回复“ ok”时,将调用(检查程序的)主服务,并验证是否请求了用户名和/或密码。
呼叫者然后根据答复继续。
最后,无论哪种解决方案都尽可能快地起作用。像上面提到的redis这样的内存'db'有点接近-考虑到差异,这意味着足够接近。如果一家大型公司的业绩为10分,而一个简单的网站按照相似的做法(遵循相同的原则)的业绩为8-9分,且成本根据每个公司的规模进行了调整,那么我认为这是一个成功的选择。