计算多个表名称出现在字符串列中的次数

时间:2018-05-26 11:55:23

标签: mysql

我正在尝试计算mysql.general_log表中出现多个表名的次数。

例如mysql.general_log表,参数列的值如下:

+------------------------------------------------------------------------------+
| argument                                                                     |
+------------------------------------------------------------------------------+
| SET GLOBAL general_log = 'ON'                                                |
| SELECT * FROM TABLEB WHERE val = 1 LIMIT 0, 1000                             |
| SHOW INDEX FROM 'DB1'.'TABLEB'                                               |
| DELETE FROM TABLEC WHERE val = 1                                             |
| UPDATE TABLEC SET val2 = 5 where val = 8                                     |
| DELETE FROM TABLEA WHERE val = 1                                             |
| DELETE FROM TABLED WHERE val = 1                                             |
| SELECT COUNT(*) FROM TABLED WHERE val = 1 LIMIT 0, 1000                      |
| DELETE FROM TABLEB WHERE val = 1                                             |
| SELECT COUNT(*) FROM TABLEB LIMIT 0, 1000                                    |
| UPDATE TABLEB SET city = 'NYC' WHERE val IN (2,6)                            |
| SELECT name FROM TABLEA WHERE val IN (2,3) LIMIT 0, 1000                     |
| SHOW INDEX FROM ''DB1.'TABLEA'                                               |
| INSERT INTO TABLEB VALUES(34)                                                |
| INSERT INTO TABLEA VALUES(34)                                                |
| INSERT INTO TABLEA VALUES(34)                                                |
| COMMIT                                                                       |
| SET GLOBAL general_log = 'OFF'                                               |
+------------------------------------------------------------------------------+

然后目标是让表格显示每个使用的表的计数

|TABLE NAME| COUNTS 
| TABLEA   |  5
| TABLEB   |  5
| TABLEC   |  2
| TABLED   |  1

到目前为止,这是我能提出的最佳解决方案:

SELECT argument, COUNT (*) FROM mysql.general_log
    WHERE  argument LIKE '%TABLEA%'   OR
           argument LIKE '%TABLEB%'   OR
           argument LIKE '%TABLEC%'   OR
           argument LIKE '%TABLED%'
    GROUP BY argument ORDER BY TIMES ASC;

我也可以使用information_schema.TABLES并选择TABLE_SCHEMA = 'DB1';所有行来获取表名称,如果这提供了解决方案的任何线索。

1 个答案:

答案 0 :(得分:0)

缓慢而肮脏的版本(非常接近你自己的建议)

SELECT t.table_name, COUNT(l.argument)  
FROM information_schema.tables t 
LEFT JOIN mysql.general_log l 
  ON (l.argument REGEXP CONCAT('[[:<:]]',t.table_name,'[[:>:]]') = 1)
WHERE t.table_schema='DB1' 
GROUP BY t.table_name;

e.g。

SELECT t.table_name, COUNT(l.argument)  
FROM information_schema.tables t 
LEFT JOIN mysql.general_log l 
  ON (l.argument REGEXP CONCAT('[[:<:]]',t.table_name,'[[:>:]]') = 1)
WHERE t.table_schema='onemillion' 
GROUP BY t.table_name;
+---------------+-------------------+
| table_name    | COUNT(l.argument) |
+---------------+-------------------+
| citest        |                10 |
| invoice       |                 1 |
| invoice_box   |                 0 |
| invoice_myaes |                 1 |
| item          |                 1 |
| milltest      |                 2 |
| sbtest1       |                 3 |
| sbtest1_myaes |                 3 |
| sbtest2       |                 0 |
| sbtest2_myaes |                 0 |
| users         |                 6 |
| users_myaes   |                 3 |
+---------------+-------------------+
12 rows in set (0.23 sec)

如前所述,这只会为您提供包含与您的表名匹配的其他标识符的日志记录。它不会给你任何关于正在运行的语句的性质的线索,因此你不会知道这些日志行是否代表UPDATE,INSERT,SELECT等,它们都会被集中在一起。根据您的要求和可能足以进行粗略估计的表名称。

如果您有5.6或更高版本,或许更好的方法是使用performance_schema并以适当的时间间隔查询events_statements_history_long表。

e.g。

SELECT t.table_name, event_name, COUNT(e.digest_text) 
FROM information_schema.tables t
LEFT JOIN performance_schema.events_statements_history_long e 
 ON (e.digest_text LIKE CONCAT('%`',t.table_name,'`%'))
WHERE t.table_schema = 'DB1' 
GROUP BY table_name, event_name;  

除了能够按语句类型分组之外,这里的优点是mysql将规范化查询并在表名周围吊索反引号,这样您就可以确定标识符的完全匹配。默认情况下,MySQL不会对此表进行收集,因此您可能需要在setup_instruments内启用它,并使用--performance-schema-events-statements-history-long-size=a_suitably_large_number调整要在服务器启动时收集的历史记录数量。

Full details on performance_schema