【问题标题】:Cross-checking a list of users with users on a db - bad idea?交叉检查用户列表与数据库上的用户 - 坏主意?
【发布时间】:2011-03-24 17:32:45
【问题描述】:

让我们说。如果我在我的系统上注册了 1,000,000 个用户,并且我有一个包含 500 个名称的列表。

我想将这些名称与我系统上的用户数量进行交叉检查,以查看哪些名称/用户已在数据库上注册。

这样的过程会显着减慢应用程序的速度吗?还是这种事情经常发生?

也许我可以每 30 分钟缓存一次结果,这样我就不必每次都调用它。

编辑>>一点澄清:

我忘了提到我正在尝试更新 500 个名字的列表。因此,如果 'foobar' 和 'joe' 在此列表中并且也在数据库中注册,那么我要做的就是从列表中删除 'foobar' 和 'joe',给我 498 个名称。

我认为不适合做这样的事情:

User.where('name in (?)', Array('foobar', 'joe'))

我会做这样的事情:

User.each do |registered_user|
  index = list.index(list.find{ |user| user.screen_name.downcase == registered_user.screen_name.downcase })
  list.delete_at(index) if index
end

filtered_list = list

上面的代码,矫枉过正吗?

【问题讨论】:

    标签: sql ruby-on-rails database postgresql


    【解决方案1】:

    任何值得称道的现代关系数据库都应该能够轻松地对数据库进行 500 次检查,而不会影响其他查询,假设您的表结构正确(唯一键、频繁搜索字段的索引、等)

    【讨论】:

      【解决方案2】:

      如果你做得聪明,它会非常快。让数据库完成工作。

      SELECT * FROM USERS WHERE Name IN ( <generated list of your 500 user name candidates>)
      

      返回的列表将是数据库中已存在的 500 个列表。比如调用会很快,在慢数据库上最多几秒钟。

      干杯, 丹尼尔

      【讨论】:

      • 还要确保名称已编入索引。
      • 在数据库级别或应用级别进行交叉检查更好吗?
      • 最好对数据库进行尽可能少的查询,因为到数据库的往返比运行内存代码慢几个数量级。数据库应该能够非常快速地执行此查询,尤其是在您为 name 列编制索引的情况下。所以让数据库来做这项工作。这是一个简单的查询,几乎不会出错。
      • 如果您在代码中生成列表(而不是子查询),请注意以下事项 - 1) sql 注入攻击 2) 某些 DB 对“IN”子句的大小有限制,所以我认为根据数据的大小,500 个条目可能有点冒险。
      • Oracle 在列表中限制为 1000 个元素。因此,当使用 Oracle 时,我将我的子句分成 998 个左右的集合。
      猜你喜欢
      • 2013-09-23
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 2015-04-25
      • 2016-08-31
      • 1970-01-01
      相关资源
      最近更新 更多