4

Impact of Querying Table Information From information_schema

 1 year ago
source link: https://www.percona.com/blog/impact-of-querying-table-information-from-information_schema/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Impact of Querying Table Information From information_schema

March 27, 2023

Carlos Tutte

On MySQL and Percona Server for MySQL, there is a schema called information_schema (I_S) which provides information about database tables, views, indexes, and more.

A lot of useful information can be retrieved from this schema, for example, table metadata and foreign key relations, but trying to query I_S can induce performance degradation if your server is under heavy load, as shown in the following example test.

Disclaimer: This blog post is meant to show a less-known problem but is not meant to be a serious benchmark. The percentage in degradation will vary depending on many factors {hardware, workload, number of tables, configuration, etc.}.

The test compares a baseline of how the server behaves while “under heavy load but no queries against I_S” vs. ” under heavy load + I_S queries” to check for performance degradation.

The same tests have been executed in Percona Server for MySQL 5.7 and 8.0. The queries executed against I_S to check performance degradation checks information about some table FKs (foreign keys) relationships.

Setup

The setup consists of creating 10K tables with sysbench and adding 20 FKs to 20 tables.

Hardware

Number of CPUs: 12

Memory size: 12288 MB

Main Percona Server for MySQL configuration variables tuned in my.cnf:

Open-files-limit = 65535
Table-definition-cache = 4096
Table-open-cache = 2000
Table_open_cache_instances = 1
Innodb-buffer-pool-size = 10G
Innodb_buffer_pool_instances = 2

You can review the full my.cnf file here: https://github.com/ctutte/blog_IS/blob/master/my.cnf

Executed queries

To generate the database setup, I used sysbench with the following flags:

Shell
sysbench --db-driver=mysql --mysql-user=root --mysql-password=123456Ab!
   --mysql-db=test --range_size=100
   --table_size=2250 --tables=10000 --threads=12 --events=0 --time=120  
   --rand-type=uniform /usr/share/sysbench/oltp_read_only.lua prepare

Then manually created 20 FKs:

Shell
ALTER TABLE sbtest1 ADD FOREIGN KEY (id) REFERENCES sbtest8001 (id);
ALTER TABLE sbtest2 ADD FOREIGN KEY (id) REFERENCES sbtest8002 (id);
{repeat 20 times}

After the scenario was set up, I executed three runs of sysbench with the following query:

Shell
sysbench --db-driver=mysql --mysql-user=root --mysql-password=123456Ab!
   --mysql-db=test --range_size=100
   --table_size=2250 --tables=1000 --threads=10 --events=0 --time=60
   --rand-type=uniform /usr/share/sysbench/oltp_read_write.lua --report-interval=1 run

To query against I_S, I used the following bash command line, which checks FK in a while loop from bash:

Shell
while true; do { mysql -u root -p123456Ab! -e "SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL"; }; done

Considering that the server has 12 vCPUs and sysbench is using 10, then there is some spare CPU capacity for running the queries against I_S, right? Let’s see the results.

Results for Percona Server for MySQL 5.7

Three runs of 60 seconds and 1000 tables:

Total queries per second
Without FK check 8337600 46320
With FK checks 6924900 38472

It can be seen that only running sysbench, 46320 queries per second, could be executed on the server.

In the scenario where I checked sysbench + I_S queries to check FKs continuously, 38472 queries per second were executed. That is (46320 – 38472) * 100 / 46320 = 16.9% performance degradation.

If the I_S queries were CPU bound, then I would expect the server to be able to do more than 46320 QPS, but something is going on, and actually, the amount of QPS did go down.

The reason for this performance degradation is that querying against I_S will need to open tables frm files (limited by table_open_cache variable).

In my example test, when running only sysbench, the workload shows few Table_open_cache_misses (the first column is initial value, each successive value is delta increase per second).

Table_open_cache_misses while NOT checking for FKs:

Shell
58437 28  15 13 7 5 7 6 1 0 0 1 0 3 8 10 5 0 0 0 0 0 0 1 0 5 0 6 5 7 5 4 0 2 2 4 6 1 0 0 0 0 0 0 0 0 0 0 0

Whereas when running sysbench + I_S queries, there is a greater number of Table_open_cache_misses due to MySQL/Percona Server for MySQL 5.7 having to open each table.frm (and in which my test runs, I have purposely read a very high number of tables compared to “Table-open-cache” variable).

Table_open_cache_misses while checking for FKs:

Shell
68133 30   31 33 30 32 31 31 29 32 28 32 30 3230 33 31 30 31 28 31 31 33 32 33 29 33 34 32 31 33 30 28 34 33 30 29 29 29 25 30 31 29 33 27 29 29 28 28

The above outputs were generated using pt-stalk + pt-mext from Percona Toolkit.

This can also be seen using Percona Monitoring and Management (PMM) and checking the “MySQL overview” dashboard ->“MySQL table open cache status” graphic.

When running only sysbench, there is a high number of cache hits (~99.98%) and a low number of “misses,” which means the table_cache is big enough for the workload.

MySQL table open cache status

Whereas while running sysbench + I_S queries, there is a decrease in the number of cache hits at ~15:33:40 when FK checks executed until ~15:35:00, which also shows an increase in (table) “Openings” and “Misses” for the duration of the test.

PMM_withFK.jpg
MySQL open cache

Performance degradation when querying against I_S can be minimized if:

Results for Percona Server for MySQL 8.0

For MySQL and Percona Server for MySQL 8, executing sysbench + I_S queries shows there almost no cache misses, as can be seen in the following snapshot:

PMM_8withFK.jpg

MySQL 8 improved data dictionary access, which avoids having to open all tables .frm files. This improvement has been ported to Percona Server for MySQL 8.

Conclusion

In conclusion, checking table information from 5.7 I_S relies on opening .frm files from disk to retrieve table information, which can cause a performance drop when the amount of opened tables does not fit in the table_cache.

If you rely heavily on queries against information_schema, then your workload will benefit from upgrading to MySQL/Percona Server for MySQL 8 because of the new data dictionary format. While you are on 5.7, you can also consider increasing table_open_cache to avoid table_misses or at least use some filters on the “WHERE” clause to avoid opening all .frm files and limit the query to a subset of the tables for a limited performance impact.

Percona Distribution for MySQL is the most complete, stable, scalable, and secure open-source MySQL solution available, delivering enterprise-grade database environments for your most critical business applications… and it’s free to use!

Try Percona Distribution for MySQL today!

Share This Post!

Subscribe
Connect with
guest
Label
0 Comments

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK