MySQL删除几条记录需要很多(40)秒,而选择相同的数据则很快
有人能解释一下为什么删除语句需要更多的时间来执行吗?我们没有创建任何触发器或级联。当从5.5迁移到8.0时,我们开始注意到这个问题。这是与8.0参数调整相关的问题吗MySQL删除几条记录需要很多(40)秒,而选择相同的数据则很快,mysql,database,performance,dml,Mysql,Database,Performance,Dml,有人能解释一下为什么删除语句需要更多的时间来执行吗?我们没有创建任何触发器或级联。当从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 T
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语句的分析信息
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 ....
这不是答案,但它有助于找到花这么多时间的地方。使用配置文件
SET PROFILING=ON;
关键词是“MyISAM”。可能需要很长时间的原因有很多
(我假设两个表在userid
?上都有索引,并且列定义相同?)
将非常快,因为它将只使用索引查找有问题的用户ID。0.05秒似乎“太慢了”SELECT
- MyISAM将在
期间执行表锁定DELETE
- MyISAM将每一行存储在.MYD文件中的某个位置。索引位于.MYI文件中,甚至对于主键也是如此
- 我认为一行是通过更改行的初始字节删除的。(实际上是一个字节,其唯一目的是指示已删除
- 在MyISAM中,通常一行是.MYD.Deletes中连续的字节流,一些更新会在.MYD中留下漏洞
- “插入”首选先填充孔,如果填充失败,则增加文件。请注意,一个大行将是一个片段的链接列表。这可能会导致整行选择越来越慢
- 甲骨文计划除掉MyISAM
SHOW CREATE TABLE
和EXPLAIN DELETE…
;可能有您遗漏的细节或我错误地假设的细节
一句话:换成InnoDB,这些问题就会消失。这两个表上都有索引吗?检查
EXPLAIN
,看看这两个查询都发生了什么。请注意,EXPLAIN的上述两个语句是相同的,而后面的语句只需要几毫秒。我怀疑是锁争用。SELECT不是n需要在磁盘上写一些东西,而DELETE需要。@Akina,从磁盘上删除9条记录40秒似乎合适吗?@Akina,我们在将form 5.5迁移到8.0时开始注意到这个问题。这两个表都在myISAM上。我们已经在SHOW PROFILE ALL上验证了innodb_file_per_表;命令为DELETE语句返回零行,而f或者SELECT语句返回21行。我看不到DELETE的行。@Cbpro Ads-您能发布分析的结果吗(SELECT和DELETE)我已经为SELECT语句添加了配置文件。很遗憾,DELETE语句没有行矩形。@Cbpro Ads-对不起,您可以将表和一些示例数据放在上面,我可以对其进行测试。最后我得到了DELETE语句的配置文件。我可以看到此行占用了大部分时间。这是CPU时间(43.15秒)。执行50.240687 19.046875 43.156250\N\N\N\N\N\N\N SELECT_LEX_UNIT::ExecuteIterat sql_union.cc 1409更改为InnoDB非常有效。我想说,MYSQL使用在8.0版本之前的版本中,我们使用了MyISAM,但从未有过这样明显的缺陷issues@CbproAds-向InnoDB添加FULLTEXT
和SPATIAL
,再加上数据字典,是Oracle为弃用MyISAM而采取的最后一个重大步骤。现在,没有什么能阻止他们获得摆脱MyISAM。我没有看到任何其他实际破坏的迹象(除了你神秘的性能问题)。
**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>