【问题标题】:Performance issue in mysql 5.6mysql 5.6 中的性能问题
【发布时间】:2019-09-20 20:04:01
【问题描述】:

我在向 mysql 中的表插入、选择和更新行时面临严重的性能问题。

我使用的表结构

CREATE TABLE `sessions` (
     `sessionid` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
     `expiry` datetime NOT NULL,
     `value` text NOT NULL,
     `data` text,
     PRIMARY KEY (`sessionid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sessions';

我面临问题查询是:

INSERT INTO sessions (SESSIONID, EXPIRY, DATA, VALUE) VALUES ('b8c10810c505ba170dd9403072b310ed', '2019-05-01 17:25:50', 'PFJlc3BvbnNlIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM', '7bKDofc/pyFSQhm7QE5jb6951Ahg6Sk8OCVZI7AcbUPb4jZpHdrCAKuCPupJO14DNY3jULxKppLadGlpsKBifiJavZ/');

UPDATE sessions SET EXPIRY = '2019-05-01 17:26:07' WHERE (SESSIONID = 'e99a0889437448091a06a43a44d0f170');

SELECT SESSIONID, EXPIRY, DATA, VALUE FROM sessions WHERE (SESSIONID = '507a752c48fc9cc3043a3dbe889c52eb');

我尝试解释查询,但无法推断出有关优化表/查询的太多信息。

从慢查询报告所用时间

对于选择平均是 23.45,对于更新是 15.93,对于插入是 22.31.

非常感谢您在确定问题方面的任何帮助。

【问题讨论】:

  • long_query_time的设置是什么?如果它是默认值 10(秒),则它只捕获少数查询。尽管如此,这些还是不合理的高。是否同时进行了备份? ALTER TABLE?还有什么“大”?
  • long_query_time 是 10 秒。没有配置备份,我们也没有做任何 DDL 操作。
  • 也许数百个这样的查询同时运行?看看你能不能用SHOW PROCESSLIST;

标签: mysql database database-performance query-performance


【解决方案1】:

每秒多少次查询?

桌子有多大?

多少内存?

innodb_buffer_pool_size 的值是多少?

UUID 不利于性能。 (那是 SHA1 吗?)这是因为它们非常随机,以至于“下一个”查询(您提到的任何查询)可能不在缓存中,因此需要磁盘命中。

因此,对于比 buffer_pool 大得多的表,旋转驱动器每秒将无法维持超过 100 个查询。 SSD 会更快。

更多关于 UUID 的弊端(SHA1 具有相同的不幸属性,但没有像 uuid 那样的解决方案):http://mysql.rjweb.org/doc.php/uuid

您可以做的一件小事是缩小表格:

session_id BINARY(20)

插入/更新/删除时使用UNHEX(),选择时使用HEX()

更多

51KB avg row len --> TEXT 列很大,并且“不记录”,因此需要多个块来处理一行。

0.8GB 缓冲池,但有 20GB 数据,以及“随机”PRIMARY KEY --> 缓存几乎没用。

这意味着对于 每个 查询将有多个 disk 命中,但可能低于 10。

300 毫秒(很快)--> HDD 上大约 30 次磁盘命中(SSD 上更多;你有哪些?)。

所以,我必须猜想,查询的 20 秒发生在突发的活动中,导致查询相互绊倒,导致大量 I/O 争用。

怎么办?大多数数据看起来像十六进制。如果这是真的,您可以通过打包和使用BINARY(..)BLOB 将磁盘占用空间减半(并减少一些所需的磁盘命中)。

INSERT INTO sessions (SESSIONID, EXPIRY, DATA, VALUE)
    VALUES (UNHEX('b8c10810c505ba170dd9403072b310ed'),
            '2019-05-01 17:25:50',
            UNHEX('PFJlc3BvbnNlIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM'),
            UNHEX('7bKDofc/pyFSQhm7QE5jb6951Ahg6Sk8OCVZI7AcbUPb4jZpHdrCAKuCPupJO14DNY3jULxKppLadGlpsKBifiJavZ/'));

UPDATE sessions SET EXPIRY = '2019-05-01 17:26:07'
 WHERE SESSIONID = UNHEX('e99a0889437448091a06a43a44d0f170');

SELECT SESSIONID, EXPIRY, DATA, VALUE FROM sessions
 WHERE SESSIONID = UNHEX('507a752c48fc9cc3043a3dbe889c52eb');

 `sessionid` VARBINARY(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
 `expiry` datetime NOT NULL,
 `value` BLOB NOT NULL,
 `data` BLOB,

ROW_FORMAT=DYNAMIC 可能是最佳选择(但这并不重要)。

【讨论】:

  • 每秒最多 20 - 40 次查询,最多 20000 行,10 GB RAM,innodb_buffer_pool_size 为 772800512,我使用的是使用强加密伪随机数生成器生成的 UUID。
  • InnoDB,版本 10,row_format 紧凑,行 391,avg_row_length 50995,data_length 19939328,max_data_length 0,index_length 0,data_free 76546048
  • 我们没有使用 SSD 驱动器。正是在窥视时间,我们一直在遇到这个问题。你的建议看起来不错,我会试试看。
  • @Delon - 由于数据远小于 buffer_pool_size,我看不到 RAM 问题。让我们分析您的设置;见mysql.rjweb.org/doc.php/mysql_analysis#tuning
【解决方案2】:

您的查询看起来不错,但问题出在您的服务器上,它可能没有足够的内存来处理此类请求,您可以增加数据库服务器的内存以获得优化的响应

【讨论】:

  • 也阅读此stackoverflow.com/questions/172925/…了解更多详情
  • 我可以看到响应时间并不一致,它有时会在 300 毫秒内响应,有时是 20-60 秒。
  • @Delon - 即使在缓存和内存大小最坏的情况下,单行查询(选择/更新/删除/插入)也不应该超过一秒钟。一定有别的事情发生了??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 2016-09-05
  • 2016-02-21
  • 1970-01-01
相关资源
最近更新 更多