【问题标题】:simple update query taking very long to execute in MySQL在 MySQL 中执行简单的更新查询需要很长时间
【发布时间】:2020-03-23 14:26:58
【问题描述】:

我在查看 MySQL 的慢查询日志,发现如下条目:

# Time: 131108  4:16:34

# Query_time: 14.726425  Lock_time: 0.000000 Rows_sent: 0  Rows_examined: 1
SET timestamp=1383884194;
UPDATE `Artist` SET ImageFilename = NULL, Title = 'Elton John', PopularityRating = 657, UniqueID = NULL, Description = NULL, IsFeatured = 0, FeaturedText = '', MetaDescription = '', MetaTitle = NULL, _Temporary_LastUpdOn = '2013-11-08 04:15:58 ', _Temporary_Flag = 0, _Deleted = 0, _DeletedOn = NULL, Priority = 0 WHERE ID = 3449748;

如您所见,执行此查询花费了惊人的 14.72 秒,而这是一次简单的更新,仅使用主键 WHERE。我试过重新执行查询,但现在它在 0.095 秒内执行,这更合理。

任何想法我可以如何调试为什么在那个特定的时间花了这么长时间?

编辑 1:query_cache% 变量

mysql> SHOW variables where variable_name like 'query_cache%';
+------------------------------+-----------+
| Variable_name                | Value     |
+------------------------------+-----------+
| query_cache_limit            | 1048576   |
| query_cache_min_res_unit     | 4096      |
| query_cache_size             | 210763776 |
| query_cache_type             | ON        |
| query_cache_wlock_invalidate | OFF       |
+------------------------------+-----------+

编辑 2:艺术家表信息

CREATE TABLE `artist` (
  `ID` bigint(20) NOT NULL,
  `ImageFilename` mediumtext,
  `Title` varchar(1000) DEFAULT NULL,
  `PopularityRating` int(11) DEFAULT '0',
  `UniqueID` mediumtext,
  `Description` mediumtext,
  `IsFeatured` tinyint(1) DEFAULT '0',
  `FeaturedText` mediumtext,
  `_Temporary_LastUpdOn` datetime DEFAULT '0001-01-01 00:00:00',
  `_Temporary_Flag` tinyint(1) DEFAULT '0',
  `_Deleted` tinyint(1) DEFAULT '0',
  `_DeletedOn` datetime DEFAULT NULL,
  `Priority` int(11) DEFAULT '0',
  `MetaDescription` varchar(2000) DEFAULT NULL,
  `MetaTitle` mediumtext,
  PRIMARY KEY (`ID`),
  KEY `_Temporary_Flag` (`_Temporary_Flag`),
  KEY `_Deleted` (`_Deleted`),
  KEY `Priority` (`Priority`),
  KEY `PopularityRating` (`PopularityRating`),
  KEY `Title` (`Title`(255)),
  KEY `IsFeatured` (`IsFeatured`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

【问题讨论】:

  • 可能那个时候表被锁住了。
  • 您是否启用了缓存?可能有点牵强,但如果查询更改了缓存结果,则可能会出现性能下降。
  • @KayNelson 我如何知道我是否启用了缓存?
  • @KarlCassar 执行这个 SHOW variables where variable_name like 'query_cache%';
  • 你能把SHOW CREATE TABLE Artist的输出贴出来吗?

标签: mysql performance


【解决方案1】:

鉴于您提供的输出,我的建议是最小化您的缓存大小。当然,这只是我最好的假设,即这会导致更新时间超过 15 秒,因为查询本身在 PRIMARY KEY 上使用 WHERE 是最佳的。

由于您无法重现问题,因此很难确定。

我正在再次阅读缓存文档以获取一些信息。

当表被修改时,查询缓存中的所有相关条目都会被刷新。 这可能是您所做的更新必须刷新缓存数据的原因。

文档的另一部分

小心查询缓存的大小过大,这 增加了维护缓存所需的开销,可能超过 启用它的好处。通常以数十兆字节为单位 有利。数百兆字节的大小可能不会。

无论哪种方式,由于您启用了查询缓存,我认为这是一个很好的起点。

在生产中设置新的查询缓存

SET GLOBAL query_cache_size = 1000000;

Mysql 会自动设置大小对齐到最近的 1024 字节块。

好好阅读这个文档,它对理解很有帮助。查询缓存可以同时是您的最佳设置和最差设置。

http://dev.mysql.com/doc/refman/5.1/en/query-cache.html

【讨论】:

    【解决方案2】:

    你的桌子有问题。您为表创建了多个索引,其中包括您将在 sql.xml 中更新的字段。然后mysql每次都要重建索引。

    【讨论】:

      【解决方案3】:

      我认为你没有调整 MySQL 服务器变量,调整服务器变量以提高性能很重要。建议看一下 key_buffer_size 和 table_cache 变量。

      key_buffer_size 变量控制 MySQL 索引缓冲区可用的内存量。该值越高,可用于索引的内存越多,性能也越好。

      table_cache 变量控制表缓存可用的内存量,因此 MySQL 可以在任何给定时间保持打开的表总数。对于有很多数据库和表的繁忙服务器,应该增加这个值,以便 MySQL 可以可靠地处理所有请求。

      【讨论】:

        【解决方案4】:

        如果有人错过了上面的评论:

        也许那个时候桌子被锁了。

        由于您无法重现该问题,因此很可能是这种情况。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多