【问题标题】:Group by with Count on very large table在非常大的桌子上使用 Count 分组
【发布时间】:2015-09-10 18:25:26
【问题描述】:

我有一个非常大的表,有 25 多万条记录。

我需要从中创建一个新表,其中三个字段是唯一的。

我试过了

SELECT Field1,Field2,Field3, Count(*) FROM `Table`  group by Field1,Field2,Field3 having Count(*)>1

Mysql 内存不足

是否有更有效的方法来查找所有具有计数 > 1 的字段的唯一记录,以便我可以进一步使用它们(创建新表等)?

【问题讨论】:

  • 如果你需要计数,你必须使用group by
  • 你有 id 列 auto_inc 吗?还有多少行
  • 取决于Field1、Field2、Field3中存储的数据类型和值;您可以在WHERE 子句中使用精心构造的条件将数据分成更易于管理的不同“块”,并运行几个这样的查询来获得整体。 (例如:如果 Field1 是数值类型,数值分布大致均匀,则可以根据跨越的值的子范围进行查询;如果是字符串类型,则可以根据第一个或两个字符分隔数据。)
  • 根据数据值,您可以将 field(n) 值合成为 int
  • @drew 我有一个带有 autoinc 的 ID 列,并且每个调用的字段都有一个索引。大约 25 列和 2500 万行。

标签: mysql count out-of-memory unique


【解决方案1】:

如果您不需要计数,那么以下可能会产生您想要的:

select field1, field2, field3
form table t
where exists (select 1
              from table t2
              where t2.field1 = t.field1 and t2.field2 = t.field2 and
                    t2.field3 = t.field3 and t2.id > t.id
             ) and
      not exists (select 1
                  from table t2
                  where t2.field1 = t.field1 and t2.field2 = t.field2 and
                        t2.field3 = t.field3 and t2.id < t2.id
                 );

第一个子句保证存在不止一行。第二个只返回组合的最小 id。

我确实意识到,要在有限时间内完成,您需要在三个字段上建立索引:

create index idx_table_field1_field2_field3 on table(field1, field2, field3)

如果group by 失败,那么这也可能失败。但是,如果它成功了,那么这个方法实际上可能非常快——假设索引可以放入内存。

【讨论】:

  • @Gordan 即使使用我的原始查询,三个字段上的索引一起也可以解决问题。我认为在每个字段上都有一个索引就足够了,但显然它是组所必需的。谢谢!
  • @user3649739 。 . .有趣的。让 MySQL 使用索引进行聚合可能具有挑战性,但这显然是可以正常工作的情况。
【解决方案2】:

不更改服务器内存配置的可能解决方案是:

CREATE TEMPORARY TABLE ttt AS 
SELECT Field1,Field2,Field3, Count(*) AS counter
FROM `Table`  group by Field1,Field2,Field3;

这可能会防止内存不足,因为不需要评估 have 子句。然后再次对 counter>1 的表 ttt 运行查询。

您必须进行测试以查看它是否有效。它会很慢(尤其是第二个查询,因为它没有可以在临时表上使用的索引,并且当您只运行该 where 语句时,第一次创建索引没有用处)。

【讨论】:

    猜你喜欢
    • 2016-08-29
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多