检查数据库中存在的大量字符串的有效方法

时间:2019-04-10 09:37:39

标签: java php sql database logic

我在数据库中有一个非常大的表,该表有一个名为 “ unique_code_string”,该表几乎有1亿条记录。

每2分钟,我将收到100,000个代码字符串,它们位于一个数组中,并且彼此唯一。如果它们都是“好的”,我需要将它们插入大表。 “好”的意思是: 数组中的所有100,000个代码都永远不会出现在数据库大表中。

如果数据库大表中出现一个或多个代码,则整个数组将完全不使用, 这意味着数组中的任何代码都不会插入到大表中。

目前,我使用这种方式: 首先,我做一个循环,检查数组中的每个代码,以查看数据库大表中是否已经有相同的代码。 其次,如果所有代码都是“新的”,那么我将进行真正的插入。 但是这种方式非常慢,我必须在2分钟内完成所有操作。

我在想其他方式:

  1. 在SQL“ in子句”中加入100,000个代码,每个代码的长度为32,我认为没有数据库会接受此32 * 100,000长度的“ in子句”。

  2. 使用数据库事务,无论如何我都会强制插入代码,如果发生错误,则事务回滚。这会导致一些性能问题。

  3. 使用数据库临时表,我不擅长编写SQL查询,如果这个想法可行,请给我一些示例。

现在,有专家可以给我一些建议或解决方案吗?

我不是英语使用者,希望您能看到我要解决的问题。

非常感谢您。

2 个答案:

答案 0 :(得分:1)

将100,000行加载到表中!

在原始表上创建唯一索引:

create unique index unq_bigtable_uniquecodestring on bigtable (unique_code_string);

现在,您拥有所需的工具。我想我会去交易,像这样:

insert into bigtable ( . . . )
    select . . . 
    from smalltable;

如果任何行失败(由于唯一索引),则事务将失败并且不插入任何内容。您也可以明确:

insert into bigtable ( . . . )
    select . . . 
    from smalltable
    where not exists (select 1
                      from smalltable st join
                           bigtable bt
                           on st.unique_code_string = bt.unique_code_string
                      );

对于此版本,您还应该在smalltable(unique_code_string)上具有索引/唯一约束。

答案 1 :(得分:0)

仅凭很少的信息就很难找到最佳解决方案。通常,这取决于应用程序与数据库服务器以及硬件资源之间的网络延迟。

  1. 您可以从数据库中加载100,000,000 unique_code_string,并使用HashSetTreeSet来删除内存中重复数据,然后再插入数据库。如果您的数据库服务器受到资源限制,或者网络延迟很大,则可能会更快。

  2. 根据您如何接收100,000条记录增量,可以将其加载到数据库中,例如可以使用external table读取CSV文件。如果可以将数据有效地放入临时表中,并且数据库服务器没有过载,则可以使用SQL或存储过程来非常有效地进行处理。

您应该花一些时间来了解更新的实时性,例如有多少SQL查询正在读取100,000,000行表,您是否可以在更新行时允许其中一些SQL查询被取消或阻止。通常,创建影子表是个好主意:

  • 创建新表作为现有100,000,000行表的副本。
  • 禁用新表上的索引
  • 将增量行加载到新表中
  • 在新表上重建索引
  • 删除现有表
  • 将新表重命名为现有的100,000,000行表

这里的方法是特定于数据库的。这将取决于您的数据库如何定义索引,例如如果您有partitioned table,则没有必要。