Wie bestimmen Sie bei einer MySQL-Abfrage physische und logische E / A?

7

Ich bin es gewohnt, einen Showplan in Microsoft SQL zu haben, und bin faul geworden, Tools zum Optimieren von MySQL-Abfragen zu verwenden. Wie kann ich physische / logische E / A für eine Abfrage in MySQL ermitteln? (EXPLAIN zeigt die Indexauswahl an, aber ich möchte, wenn möglich, weitere Informationen vom MySQL-Server).

David Hall
quelle
2
Ich nehme an, du hast das auf SO gesehen? hilft es? stackoverflow.com/questions/124925/… Wenn nicht, warum nicht?
jcolebrand
Nicht ganz Ihre Frage, aber vielleicht gefällt Ihnen dieser Blog-Beitrag: tocker.ca/2013/05/06/when-does-mysql-perform-io.html
Morgan Tocker

Antworten:

6

Ich empfehle die Verwendung von Percona Server für die Verbesserungen des langsamen Abfrageprotokolls. Ich habe einen ähnlichen Thread zu Stack Overflow beantwortet:

/programming/3393206/what-is-the-equivalent-query-in-mysql/3443944#3443944

Schauen Sie sich dies insbesondere an (von http://www.percona.com/docs/wiki/percona-server:features:slow_extended?redirect=1#changes_to_the_log_format ):

# User@Host: mailboxer[mailboxer] @  [192.168.10.165]
# Thread_id: 11167745  Schema: board
# QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: Yes  Disk_tmp_table: No
# Filesort: Yes  Disk_filesort: No  Merge_passes: 0
# Query_time: 0.000659  Lock_time: 0.000070  Rows_sent: 0  Rows_examined: 30  Rows_affected: 0  Rows_read: 30
#   InnoDB_IO_r_ops: 1  InnoDB_IO_r_bytes: 16384  InnoDB_IO_r_wait: 0.028487
#   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
#   InnoDB_pages_distinct: 5
select count(distinct author_id) from art87.article87 force index (forum_id) where forum_id = 240215 and thread_id = '710575' 
Morgan Tocker
quelle
4

Sie können die Abfrageleistung anhand der Anzahl der Festplattensuchen abschätzen.

Im Abschnitt " Optimierung" des MySQL-Handbuchs wird eine der nützlicheren Methoden zum Schätzen von E / A und nachfolgenden Optimierungsanforderungen erläutert. Wenn Sie die Anzahl der Lesevorgänge untersuchen und die Hardware-E / A schätzen, sollten Sie einen ziemlich klaren Hinweis auf die Anforderungen für den Festplattenzugriff erhalten. Durch Anpassen der Puffergrößen können Sie außerdem die Auswirkungen von Speicher und Caching auf Ihre Abfrage erkennen.

Brian Ballsun-Stanton
quelle
3

Es ist nicht perfekt, aber Sie sollten es können

mysql> show variables where variable_name like '%innodb%';

Die Anzahl der physischen Lesevorgänge finden Sie am Innodb_buffer_pool_readsZähler und die Anzahl der logischen Lesevorgänge Innodb_buffer_pool_read_requests. Um nützlich zu sein, müssten Sie diese Zahlen notieren, dann eine repräsentative Arbeitslast ausführen und dann die Anzahl der logischen Lesevorgänge teilen, um logische Lesevorgänge pro Abfrage zu finden. Wenn Sie Glück haben, erhöht sich die Anzahl der physischen Lesevorgänge zu Beginn Ihres Testlaufs und bleibt dann konstant.

Gaius
quelle
Nützlich, aber beachten Sie, dass dies global ist: Wenn Sie eine Aussage studieren, sollten Sie besser allein sein. Außerdem ist es manchmal irreführend, wenn Sie denselben Block mehrmals neu lesen. Er wird jedes Mal als logischer Lesevorgang gezählt (Beispiel: Verbinden Sie 1000 Zeilen in einer Zeile => 1000 logische Lesevorgänge, obwohl der gesamte Satz möglicherweise 100 Blöcke umfasst) Verwenden Sie dies, um einige schwere SQL zu erkennen ...
phil_w
1

Mit etwas Arbeit können Sie sehen, wie viel "Arbeit" Ihre Abfrage kostet.

mysql> FLUSH STATUS;           -- In newer MySQLs, this clears the "SESSION" values
Query OK, 0 rows affected (0.00 sec)    

mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 0     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 0     |
| Handler_read_key           | 0     |
| Handler_read_next          | 0     |
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 0     |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 0     |
+----------------------------+-------+
15 rows in set (0.00 sec)

mysql> SELECT * FROM ts;
+----+---------------------+
| id | ts                  |
+----+---------------------+
|  1 | 2011-03-24 20:47:38 |
|  2 | 2011-03-24 20:46:29 |
|  3 | 2011-03-24 20:46:43 |
+----+---------------------+
3 rows in set (0.00 sec)

mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 1     |
| Handler_read_key           | 2     |
| Handler_read_next          | 0     |
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 4     |  <-- 3 rows, plus 1 to realize it is finished
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 0     |
+----------------------------+-------+
15 rows in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Up%';
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| Uptime                    | 3287334 |
| Uptime_since_flush_status | 68      |
+---------------------------+---------+
2 rows in set (0.00 sec)

Nun, das gibt Ihnen nicht die zwischengespeicherten und nicht zwischengespeicherten Antworten, aber es gibt Ihnen einige interessante Hinweise.

Leider sind die InnoDB-STATUS global. Sie müssen sie also vorher und nachher erfassen. Schlimmer noch, andere Abfragen werden auch die Werte stoßen.

mysql> SHOW SESSION STATUS LIKE 'Innodb_buffer_pool%';
+---------------------------------------+-------------+
| Variable_name                         | Value       |
+---------------------------------------+-------------+
| Innodb_buffer_pool_pages_data         | 279861      |
| Innodb_buffer_pool_pages_dirty        | 52          |
| Innodb_buffer_pool_pages_flushed      | 15992658    |
| Innodb_buffer_pool_pages_free         | 96          |
| Innodb_buffer_pool_pages_misc         | 8043        |
| Innodb_buffer_pool_pages_total        | 288000      |
| Innodb_buffer_pool_read_ahead         | 2567477     |
| Innodb_buffer_pool_read_ahead_evicted | 262237      |
| Innodb_buffer_pool_read_requests      | 26565709230 |
| Innodb_buffer_pool_reads              | 1339717     |
| Innodb_buffer_pool_wait_free          | 0           |
| Innodb_buffer_pool_write_requests     | 865548882   |
+---------------------------------------+-------------+
12 rows in set (0.00 sec)

mysql> SELECT * FROM ts;
+----+---------------------+
| id | ts                  |
+----+---------------------+
|  1 | 2011-03-24 20:47:38 |
|  2 | 2011-03-24 20:46:29 |
|  3 | 2011-03-24 20:46:43 |
+----+---------------------+
3 rows in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool%';
+---------------------------------------+-------------+
| Variable_name                         | Value       |
+---------------------------------------+-------------+
| Innodb_buffer_pool_pages_data         | 279865      |
| Innodb_buffer_pool_pages_dirty        | 8           |
| Innodb_buffer_pool_pages_flushed      | 15992842    |
| Innodb_buffer_pool_pages_free         | 92          |
| Innodb_buffer_pool_pages_misc         | 8043        |
| Innodb_buffer_pool_pages_total        | 288000      |
| Innodb_buffer_pool_read_ahead         | 2567477     |
| Innodb_buffer_pool_read_ahead_evicted | 262237      |
| Innodb_buffer_pool_read_requests      | 26565712655 |  <-- This went up
| Innodb_buffer_pool_reads              | 1339717     |  <-- No chg = no disk reads
| Innodb_buffer_pool_wait_free          | 0           |
| Innodb_buffer_pool_write_requests     | 865550805   |
+---------------------------------------+-------------+
12 rows in set (0.00 sec)

Mein Mantra "Count the Disk Hits".

Rick James
quelle