【问题标题】:MySQL DELETE takes many (40) seconds for few records while a SELECT of the same data is fastMySQL DELETE 需要很多 (40) 秒来处理几条记录,而 SELECT 相同数据的速度很快
【发布时间】:2020-06-12 07:21:35
【问题描述】:

谁能解释一下为什么 DELETE 语句需要更多时间来执行?我们还没有创建任何 TRIGGER 或 CASCADE。当从 5.5 迁移到 8.0 时,我们开始注意到这个问题。是不是8.0参数调优的问题?

DELETE s FROM storefront s LEFT JOIN MASTER m  ON m.userid=s.userid WHERE m.userid IS NULL

9 row(s) affected 
Execution Time : 40.816 sec
Transfer Time  : 0.001 sec
Total Time     : 40.817 sec

同时,SELECT 语句只需要几毫秒。

SELECT s.userid FROM storefront s LEFT JOIN MASTER m  ON m.userid=s.userid WHERE m.userid IS NULL

Total Time     : 0.05 sec

任何帮助将不胜感激。我们有更好的服务器硬件和 16 GB 的 RAM。

这是 DELETE 语句的 PROFILING 信息。

It is CPU_user(19.046875 seconds) and CPU_system(43.156250 seconds) taking most of the time out of the total execution time 50.24 seconds ....

【问题讨论】:

  • 两张表上都有索引吗?检查EXPLAIN,看看这两个查询发生了什么。
  • 请注意,上面两个语句对于 EXPLAIN 是相同的,而后面的语句只需要几毫秒。我怀疑锁争用。
  • SELECT 不需要在磁盘上写东西,而 DELETE 需要。
  • @Akina,40 秒似乎可以从磁盘中删除 9 条记录吗?
  • @Akina,当我们从 5.5 迁移到 8.0 时,我们开始注意到这个问题。这两个表都在 myISAM 上。我们已将 innodb_file_per_table 验证为 ON

标签: mysql database performance dml


【解决方案1】:

关键字是“MyISAM”。 可能需要很长时间的原因有多种。

(我假设两个表在userid 上都有索引?并且列定义相同?)

  • SELECT 会非常快,因为它只会使用索引来查找有问题的用户 ID。 0.05 秒似乎“太慢”了。
  • MyISAM 将在DELETE 期间执行表锁定。
  • MyISAM 将每一行存储在 .MYD 文件的某个位置。索引位于 .MYI 文件中,即使对于主键也是如此。
  • 我认为通过更改行的初始字节来删除行。 (实际上是一个字节,其唯一目的是表示已删除。
  • 在 MyISAM 中,通常一行是 .MYD 中的连续字节流。删除和一些更新会在 .MYD 中留下漏洞。
  • 插入更喜欢先填充孔,如果失败则增加文件。请注意,大行将是片段的链接列表。这可能会导致越来越慢的全行选择。
  • Oracle 计划摆脱 MyISAM。

那些并没有真正加起来解释 40 秒只删除 9 行。 请提供SHOW CREATE TABLEEXPLAIN DELETE ...;您可能遗漏了一些细节,或者我错误地假设了这些细节。

底线:改用 InnoDB,这些问题就会迎刃而解。

【讨论】:

  • 改用 InnoDB 就像一个魅力。仅供参考,我想说的是,MYSQL 在早期版本中比 8.0 版更尊重 MyISAM 引擎。在 5.5 版中,我们使用了 MyISAM,但从未出现过此类明显问题
  • @CbproAds - 将 FULLTEXTSPATIAL 添加到 InnoDB 以及数据字典,是 Oracle 为弃用 MyISAM 所做的最后一个重要步骤。现在“没有什么”可以阻止他们摆脱 MyISAM。我没有看到任何其他实际破坏的迹象(除了你神秘的性能问题)。
【解决方案2】:

这不是答案,但它可以帮助找到花费这么多时间的地方。使用剖析

SET PROFILING=ON;

Manual

**sample**

mysql> SET PROFILING=ON;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select * from photons where photons >= 100;
+----+---------------------+---------+
| id | mytime              | photons |
+----+---------------------+---------+
|  1 | 2020-02-26 12:00:00 |     100 |
|  3 | 2020-02-26 12:01:00 |     100 |
|  4 | 2020-02-26 12:05:00 |     200 |
+----+---------------------+---------+
3 rows in set (0.01 sec)

mysql> SHOW PROFILE ALL;
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+----------------------+-------------+
| Status               | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out | Messages_sent | Messages_received | Page_faults_major | Page_faults_minor | Swaps | Source_function       | Source_file          | Source_line |
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+----------------------+-------------+
| starting             | 0.000130 | 0.000071 |   0.000057 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | NULL                  | NULL                 |        NULL |
| checking permissions | 0.002022 | 0.000127 |   0.000103 |                 2 |                   0 |          160 |             0 |             0 |                 0 |                 2 |                 1 |     0 | check_access          | sql_authorization.cc |         802 |
| Opening tables       | 0.000474 | 0.000040 |   0.000033 |                 1 |                   0 |            8 |             0 |             0 |                 0 |                 1 |                 1 |     0 | open_tables           | sql_base.cc          |        5715 |
| init                 | 0.000043 | 0.000023 |   0.000020 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | handle_query          | sql_select.cc        |         121 |
| System lock          | 0.000811 | 0.000046 |   0.000035 |                 2 |                   0 |           16 |             0 |             0 |                 0 |                 2 |                 2 |     0 | mysql_lock_tables     | lock.cc              |         323 |
| optimizing           | 0.000474 | 0.000027 |   0.000023 |                 1 |                   0 |            8 |             0 |             0 |                 0 |                 1 |                 1 |     0 | optimize              | sql_optimizer.cc     |         151 |
| statistics           | 0.000027 | 0.000014 |   0.000012 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | optimize              | sql_optimizer.cc     |         367 |
| preparing            | 0.000763 | 0.000044 |   0.000036 |                 2 |                   0 |           16 |             0 |             0 |                 0 |                 2 |                 2 |     0 | optimize              | sql_optimizer.cc     |         475 |
| executing            | 0.000007 | 0.000003 |   0.000003 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | exec                  | sql_executor.cc      |         119 |
| Sending data         | 0.000103 | 0.000057 |   0.000046 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | exec                  | sql_executor.cc      |         195 |
| end                  | 0.001408 | 0.000062 |   0.000050 |                 1 |                   0 |          248 |             0 |             0 |                 0 |                 1 |                 0 |     0 | handle_query          | sql_select.cc        |         199 |
| query end            | 0.000378 | 0.000029 |   0.000022 |                 1 |                   0 |            8 |             0 |             0 |                 0 |                 1 |                 1 |     0 | mysql_execute_command | sql_parse.cc         |        4946 |
| closing tables       | 0.000409 | 0.000022 |   0.000020 |                 1 |                   0 |            8 |             0 |             0 |                 0 |                 1 |                 1 |     0 | mysql_execute_command | sql_parse.cc         |        4998 |
| freeing items        | 0.000030 | 0.000017 |   0.000012 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | mysql_parse           | sql_parse.cc         |        5610 |
| cleaning up          | 0.000026 | 0.000014 |   0.000012 |                 0 |                   0 |            0 |             0 |             0 |                 0 |                 0 |                 0 |     0 | dispatch_command      | sql_parse.cc         |        1924 |
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+----------------------+-------------+
15 rows in set, 1 warning (0.00 sec)

mysql> 

【讨论】:

  • 显示个人资料全部;命令为 DELETE 语句返回 0 行,而 SELECT 语句返回 21 行。我看不到 DELETE 的行。
  • @Cbpro Ads - 您能否发布分析结果(选择并删除)
  • 我为 SELECT 语句添加了 PROFILE。不幸的是,DELETE 语句没有返回任何行。
  • @Cbpro Ads - 抱歉,您能否将表格和一些示例数据放在 sqlfiddle.com 上,我可以对其进行测试
  • 最后我得到了 DELETE 语句的 PROFILING。我可以看到这条线占用了大部分时间。它是 CPU 时间(43.15 秒)。执行 50.240687 19.046875 43.156250 \N \N \N \N \N \N \N \N \N SELECT_LEX_UNIT::ExecuteIterat sql_union.cc 1409
猜你喜欢
  • 2018-08-02
  • 2018-10-17
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 2013-02-05
  • 2021-05-02
  • 1970-01-01
相关资源
最近更新 更多