Kat*_*kas 9 mysql optimization
我正在优化我们的数据库。本质上,我试图在我们的数据库中找到写入次数最多和读取次数最多的表。之后,我将把这些表符号链接到单独的驱动器中。
有没有办法跟踪每个表的活动?如下所示,每个表的 IOPS、写入、读取?
Aar*_*own 10
方法一
如果您使用的是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 |
+-------------------+------------+--------------+------------------------+
Run Code Online (Sandbox Code Playgroud)
ROWS_CHANGED 将对应于写入最多的表,而 ROWS_READ 将对应于最多的读取。您还应该查看 INDEX_STATISTICS 以找到最常用和最不常用的索引。
另请参阅MariaDB 用户统计文档。
方法二
如果您没有使用 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;
Run Code Online (Sandbox Code Playgroud)
现在你有一个文件, /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
Run Code Online (Sandbox Code Playgroud)
如果您检查/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
Run Code Online (Sandbox Code Playgroud)
粗略地说,在您选择的示例期间,这些是您最多写入表格的内容。为了从表中获得最多的读取(大致),您可以将--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
Run Code Online (Sandbox Code Playgroud)
您还可以使用 tcpdump 和 pt-query-digest --type=tcpdump
因此,话虽如此,假设您正在使用 InnoDB 表,我非常怀疑您是否会从这样做中获得很大的性能优势。由于数据被缓冲到 InnoDB 日志然后写入磁盘的方式,我不希望通过像这样移动单个表来获得太多或任何性能提升。您可能会看到将 InnoDB 日志文件本身移动到单独的、更快的磁盘以将日志读/写与表空间读/写分开的一些好处,但即使这样也是有问题的。投资具有电池备份缓存(或更好的 SSD)的快速、高质量 RAID 阵列将更好地利用您的资源。
归档时间: |
|
查看次数: |
4528 次 |
最近记录: |