【问题标题】:Selecting duplicates gives different result count every query选择重复项会为每个查询提供不同的结果计数
【发布时间】:2019-11-20 18:00:07
【问题描述】:

我目前正在尝试删除 MySQL 5.7 (InnoDB) 中的重复行,并正在通过运行 SELECT COLUMN, COUNT(*) FROM TABLE GROUP BY COLUMN HAVING COUNT(*) > 1 检查我有多少重复的 mediumtext 列。返回的最新查询:

[results]
31620 rows in set (17.98 sec)

如果稍后我运行完全相同的查询,我会得到:

[results]
31594 rows in set (17.35 sec)

等等。我几乎每次都会得到不同的结果。查询期间没有任何内容写入数据库。 它只在这个查询中这样做; SELECT COUNT(*) FROM TABLESELECT COUNT(*) FROM TABLE WHERE COLUMN LIKE <VALUE> 等等,都会产生一致的结果。 执行SELECT COLUMN, COUNT(*) FROM TABLE GROUP BY COLUMN HAVING COUNT(*) > 0时也不会出现此错误

我不确定要提供哪些其他代码来帮助回答这个问题,因为这是我正在运行的唯一查询,而且我正在控制台中执行此操作。我正在努力思考可能是什么原因造成的。鉴于 other problems 我已经使用同一个数据库,我想知道是否有可能损坏了。

编辑:我已经运行了 1000 个查询来对结果进行抽样,结果如下:

33991的上限是最常见的结果。

表格的字符集是utf8mb4,正在聚合的列的排序规则是utf8mb4_general_ci

使用 MyISAM 时EXPLAIN SELECT COLUMN, COUNT(*) FROM COLUMN GROUP BY COLUMN HAVING COUNT(*) > 1; 的输出:

+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra                           |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+
|  1 | SIMPLE      | TABLE  | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 788685 |   100.00 | Using temporary; Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+

InnoDB 的结果:

+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra                           |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+
|  1 | SIMPLE      | TABLE  | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 769501 |   100.00 | Using temporary; Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+

到目前为止,我已经尝试过 cmets 中的建议

  • Memtest,使用memtest Linux 包并运行memtest 15G 2(系统有16G 内存,15.4 可用,大约0.4 正在使用。这是一台云机器,我不能用Memtest 启动,虽然我'我们已经向提供者提出了一个请求,看看他们是否可以。
  • 启用常规日志,显示查询之间没有运行其他活动。
  • 使用OPTIMIZE TABLE
  • 删除并重新添加索引。
  • 将表引擎从 InnoDB 更改为 MyISAM,这似乎有点帮助,因为查询现在在几次查询后达到了最大限制,但它仍然会在最初的几个查询中反弹。

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 将表转储为 SQL 并导入新的数据库实例,然后重试
  • 即使这样,I'd fear the backlash
  • 为了一致性,使用限制和命令。我不确定数据集是什么,但您可能会遇到 SQL 没有按特定顺序提取这些值的事实。如果您的查询运行到内存使用中(对于 30000 多个中等文本结果可能就是这种情况),您的查询可能会达到最大值。尝试运行相同的查询,但输入 ORDER BY COLUMN DESC 并查看是否有更一致的结果。您也可以尝试以较低的限制运行查询并执行二进制增量(例如限制 15000,然后是 25000),直到您开始得到不一致的结果。
  • @AaronMorefield 问题是,如果我执行having count(*) > 0,则不会出现此问题,它会返回更大的行集。这些相同的内存限制不会对该查询产生相同的问题吗?

标签: mysql ubuntu innodb mysql-connector


【解决方案1】:

我对 mysql 的有限知识触发了我对 TEXT 类型列的蜘蛛侠意识,我认为在 TEXT 类型列中,表中的默认存储大小为 256,其余文本大小存储在一些内部临时 mysql 表中。而且由于 mysql 客户端和 mysql 服务器的“max_allowed_pa​​cket”属性不同,我认为每次 mysql 服务器向您的客户端发送整个文本的不同子集时,都有可能导致这种歧义。

您应该能够为您的 mysql 客户端增加“max_allowed_pa​​cket”属性并验证您是否确实获得了一致的结果。

【讨论】:

  • 当查询选择count(*) > 0 时,会不会也出现此错误?
  • 当你在 mediumtext 列上分组时,mysql 数据库引擎正在读取(256 + 一些可变长度的数据),那么这个可变长度的文本每次都有可能不同,所以这个错误会起作用只要您在此 mediumtext 列上进行分组,它就可以进行任何计数查询组合。您可以尝试通过仅选择固定长度(例如前 200 个字符)来消除它,然后看到一致的结果。
【解决方案2】:
POSSIBLE KEYS  |   KEY
NULL          |  NULL

它表明当您执行分组依据时,您没有使用任何索引。 在该列上添加特定索引。

【讨论】:

  • 你的说明能再具体一点吗?
  • 当您显示 EXPLAIN 输出时。它显示为 NULL。这意味着您的表上没有索引。 MySQL 优化器尝试全面扫描所有内容。
  • 对,我的意思是具体的修复说明
  • 有两种方式: 1.dev.mysql.com/doc/refman/8.0/en/create-index.html 2.如果你有PHPmyadmin或者MySQL的客户端,你可以创建INDEX
  • 索引应该对确定性查询的结果没有影响。
猜你喜欢
  • 2014-02-11
  • 2012-01-22
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多