我正在优化数据库。本质上,我试图在数据库中找到写入最多和读取最多的表。之后,我将把这些表符号链接到单独的驱动器中。
有没有一种方法可以跟踪每个表的活动?就像在后面的IOPS中一样,每个表的写入,读取次数是多少?
我正在优化数据库。本质上,我试图在数据库中找到写入最多和读取最多的表。之后,我将把这些表符号链接到单独的驱动器中。
有没有一种方法可以跟踪每个表的活动?就像在后面的IOPS中一样,每个表的写入,读取次数是多少?
Answers:
方法1
如果您使用的是Percona Server或MariaDB(> = 5.2),则可以简单地设置userstat / userstat_running变量来启用一堆新的INFORMATION_SCHEMA表,其中包括一个名为TABLE_STATISTICS的表,该表可以准确地提供此信息。
例如:
mysql> SELECT TABLE_NAME, ROWS_READ, ROWS_CHANGED, ROWS_CHANGED_X_INDEXES FROM TABLE_STATISTICS ORDER BY ROWS_CHANGED DESC LIMIT 5;
+-------------------+------------+--------------+------------------------+
| TABLE_NAME | ROWS_READ | ROWS_CHANGED | ROWS_CHANGED_X_INDEXES |
+-------------------+------------+--------------+------------------------+
| user | 21122527 | 5989231 | 23956924 |
| audit | 1208 | 5020929 | 20083716 |
| sometemp | 13995426 | 3182150 | 9546450 |
| creditcards | 3566482 | 2998976 | 11995904 |
| order | 2147483647 | 2662606 | 53252120 |
+-------------------+------------+--------------+------------------------+
ROWS_CHANGED将对应于写入表的次数最多,而ROWS_READ将是读取次数最多的表。您还应该查看INDEX_STATISTICS来查找使用最多和使用最少的索引。
另请参阅MariaDB用户统计信息文档。
方法2
如果不使用Percona Server,则可以使用pt-query-digest捕获查询示例,然后仅过滤出INSERT / UPDATE / DELETE。看起来像这样:
mysql> SELECT @@GLOBAL.slow_query_log_file;
+------------------------------------------+
| @@GLOBAL.slow_query_log_file |
+------------------------------------------+
| /var/logs/mysql/slowquery.log |
+------------------------------------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL slow_query_log_file='/tmp/allqueries.log';
mysql> SELECT @@GLOBAL.long_query_time;
+--------------------------+
| @@GLOBAL.long_query_time |
+--------------------------+
| 0.250000 |
+--------------------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL long_query_time = 0;
mysql> FLUSH LOGS;
mysql> SLEEP 600; SET GLOBAL long_query_time = 0.25; SET GLOBAL slow_query_log_file='/var/logs/mysql/slowquery.log'; FLUSH LOGS;
现在,您有了一个文件,/tmp/allqueries.log
其中包含在服务器上执行约10分钟的每个查询。
接下来,使用pt-query-digest分析它,以将最频繁地写入表中:
pt-query-digest /tmp/allqueries.log --group-by=distill --filter '$event->{arg} =~ m/^(update|delete|insert)/i' --limit 5 > /tmp/writes.txt
如果您检查/tmp/writes.txt
,您将在顶部附近看到如下部分:
# Profile
# Rank Query ID Response time Calls R/Call Apdx V/M Item
# ==== ======== ============= ===== ====== ==== ===== ====================
# 1 0x 0.0558 26.8% 282 0.0002 1.00 0.00 INSERT UPDATE user
# 2 0x 0.0448 21.5% 246 0.0002 1.00 0.00 UPDATE audit
# 3 0x 0.0228 10.9% 11 0.0021 1.00 0.00 UPDATE sometemp
# 4 0x 0.0108 5.2% 16 0.0007 1.00 0.00 UPDATE creditcards
# 5 0x 0.0103 4.9% 43 0.0002 1.00 0.00 UPDATE order
大致来说,这些是您在选择的样本期间最经常写入表格的内容。要从表中获得最大的读取效果(大致),可以将--filter
参数更改为--filter '$event->{arg} =~ m/^select/i'
,您将看到类似的输出。
如果您只对写入感兴趣,则可以将二进制日志传递到其中pt-query-digest
并获得类似的结果:
mysqlbinlog mysql-bin.000511 | pt-query-digest --type=binlog --group-by=distill > /tmp/writes.txt
您还可以使用tcpdump和 pt-query-digest --type=tcpdump
因此,话虽如此,假设您使用的是InnoDB表,我非常怀疑您会从中获得很多性能收益。由于将数据缓冲到InnoDB日志中然后写入磁盘的方式,我不会期望像这样移动各个表而获得任何性能提升。通过将InnoDB日志文件本身移动到更快的磁盘上以将日志读/写与表空间读/写分开,您可能会看到一些好处,但是即使这样也令人怀疑。投资具有电池后备缓存(或更好的是SSD)的快速,高质量RAID阵列将更好地利用您的资源。