MySQL按表读取/写入


8

我正在优化数据库。本质上,我试图在数据库中找到写入最多和读取最多的表。之后,我将把这些表符号链接到单独的驱动器中。

有没有一种方法可以跟踪每个表的活动?就像在后面的IOPS中一样,每个表的写入,读取次数是多少?

Answers:


10

方法1

如果您使用的是Percona ServerMariaDB(> = 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阵列将更好地利用您的资源。


电池支持的缓存-您能给我一些链接以进一步了解这些内容吗?
Katafalkas,2012年

en.wikipedia.org/wiki/RAID将是一个不错的起点。对于数据库,RAID10通常优于RAID5或6。
亚伦·布朗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.