当前位置:网站首页>MySQL case deep excavation information_ Root causes of slow schema view query (Part 2)

MySQL case deep excavation information_ Root causes of slow schema view query (Part 2)

2022-06-24 02:41:00 Yaochong

Part 1 :https://cloud.tencent.com/developer/article/1893477

The next part :https://cloud.tencent.com/developer/article/1893640

Continue with the last article , Create data , Created 1.5 10000 meters , A total of 11 10000 columns

mysql> select count(*) from information_schema.columns
    -> union all
    -> select count(*) from information_schema.tables;
+----------+
| count(*) |
+----------+
|   115013 |
|    15751 |
+----------+
2 rows in set (5.54 sec)

Carry out the above SQL, You can see the execution 231 second ,state Status as checking permissions

After further observation ,1000 Seconds later ,checking permissions disappear , Then the client returns the result

checking permission During this period, I actually did two parts of work ,

  1. Check authority
  2. Traverse all the... Under the database frm file , And get relevant information .

Then bring in the conditions and query directly to find the results

SELECT c.TABLE_SCHEMA,
       c.TABLE_NAME,
       c.COLUMN_NAME,
       c.COLUMN_TYPE,
       c.IS_NULLABLE,
       c.COLUMN_COMMENT,
       c.ORDINAL_POSITION,
       (CASE

         WHEN c.EXTRA = 'STORED GENERATED' THEN
          concat('GENERATED ALWAYS AS (',
                 c.GENERATION_EXPRESSION,
                 ') STORED')
         WHEN c.EXTRA = 'VIRTUAL GENERATED' THEN
          concat('GENERATED ALWAYS AS (',
                 c.GENERATION_EXPRESSION,
                 ') VIRTUAL')
         ELSE
          c.EXTRA
       END) AS EXTRA,
       (CASE
         WHEN COLUMN_DEFAULT = "'" THEN
           "'"
         ELSE
          COLUMN_DEFAULT
       END) AS COLUMN_DEFAULT,
       (CASE
         WHEN c.DATA_TYPE = 'float' OR c.DATA_TYPE = 'double' OR
              c.DATA_TYPE = 'decimal' THEN
          c.NUMERIC_PRECISION
         ELSE
          c.CHARACTER_MAXIMUM_LENGTH
       END) AS length,
       c.NUMERIC_SCALE,
       c.DATA_TYPE,
       d.ENGINE,
       substring_index(d.TABLE_COLLATION, '_', 1) TABLE_CHARACTER,
       c.CHARACTER_SET_NAME,
       c.COLLATION_NAME,
       d.TABLE_COLLATION
  FROM information_schema.COLUMNS c, information_schema.TABLES d
 WHERE c.TABLE_SCHEMA NOT IN
       ('sys', 'mysql', 'PERFORMANCE_SCHEMA', 'information_schema')
   AND c.TABLE_SCHEMA = d.TABLE_SCHEMA
   AND BINARY c.TABLE_NAME = d.TABLE_NAME
   and d.table_schema = 'tpch'
 ORDER BY 1, BINARY c.TABLE_NAME, 7;

Time consuming 105ms

View execution plan

Without filter conditions

-> Sort row IDs: `cast(mysql.tbl.``name`` as char charset binary)`, information_schema.c.ORDINAL_POSITION
    -> Table scan on <temporary>  (cost=0.01..4100666.98 rows=328053158)
        -> Temporary table  (cost=254160304.36..258260971.33 rows=328053158)
            -> Nested loop inner join  (cost=221354988.50 rows=328053158)
                -> Nested loop inner join  (cost=188501227.21 rows=328053158)
                    -> Nested loop inner join  (cost=155647465.92 rows=328053158)
                        -> Nested loop left join  (cost=40828860.46 rows=28659105)
                            -> Nested loop left join  (cost=37962526.78 rows=28659105)
                                -> Nested loop left join  (cost=35094990.69 rows=28659105)
                                    -> Nested loop inner join  (cost=32228657.02 rows=28659105)
                                        -> Filter: (0 <> internal_get_view_warning_or_error(mysql.sch.`name`,mysql.tbl.`name`,mysql.tbl.`type`,mysql.tbl.`options`))  (cost=1766.17 rows=16929)
                                            -> Inner hash join (mysql.tbl.schema_id = mysql.sch.id)  (cost=1766.17 rows=16929)
                                                -> Table scan on tbl  (cost=1763.27 rows=16929)
                                                -> Hash
                                                    -> Nested loop inner join  (cost=2.90 rows=1)
                                                        -> Nested loop inner join  (cost=2.55 rows=1)
                                                            -> Inner hash join (no condition)  (cost=2.20 rows=1)
                                                                -> Index scan on cat using name  (cost=1.10 rows=1)
                                                                -> Hash
                                                                    -> Index scan on cat using name  (cost=1.10 rows=1)
                                                            -> Filter: (mysql.sch.`name` not in ('sys','mysql','PERFORMANCE_SCHEMA','information_schema'))  (cost=0.35 rows=1)
                                                                -> Single-row index lookup on sch using catalog_id (catalog_id=mysql.cat.id, name='tpch')  (cost=0.35 rows=1)
                                                        -> Single-row index lookup on sch using catalog_id (catalog_id=mysql.cat.id, name='tpch')  (cost=0.35 rows=1)
                                        -> Filter: ((cast(mysql.tbl.`name` as char charset binary) = mysql.tbl.`name`) and (0 <> can_access_table(mysql.sch.`name`,mysql.tbl.`name`)) and (0 <> is_visible_dd_object(mysql.tbl.hidden)))  (cost=210.76 rows=1693)
                                            -> Index lookup on tbl using schema_id (schema_id=mysql.sch.id)  (cost=210.76 rows=16929)
                                    -> Single-row index lookup on col using PRIMARY (id=mysql.tbl.collation_id)  (cost=0.00 rows=1)
                                -> Single-row index lookup on ts using PRIMARY (id=mysql.tbl.tablespace_id)  (cost=0.00 rows=1)
                            -> Single-row index lookup on stat using PRIMARY (schema_name='tpch', table_name=mysql.tbl.`name`)  (cost=0.00 rows=1)
                        -> Filter: ((0 <> can_access_column(mysql.sch.`name`,mysql.tbl.`name`,mysql.col.`name`)) and (0 <> is_visible_dd_object(mysql.tbl.hidden,(mysql.col.hidden not in ('Visible','User')))) and (mysql.col.collation_id is not null))  (cost=2.86 rows=11)
                            -> Index lookup on col using table_id (table_id=mysql.tbl.id)  (cost=2.86 rows=11)
                    -> Single-row index lookup on coll using PRIMARY (id=mysql.col.collation_id)  (cost=0.00 rows=1)
                -> Single-row index lookup on cs using PRIMARY (id=mysql.coll.character_set_id)  (cost=0.00 rows=1)

With filter conditions

Conclusion

1、 Article 1 with a SQL It takes a lot of time to verify permissions .

2、 If the query condition is , Bring in condition , Can narrow the scope of the query , This can filter out unwanted data earlier , At the same time, the permission verification operation is reduced , Save a lot of time , Let's see Oracle Definition of predicate push in

push predicate (Pushing Predicate): When SQL Statement contains views that cannot be merged , And the view has predicate filtering ( That is to say where Filter conditions ),CBO Will push the predicate filter criteria into the view , This process is called predicate push . The main purpose of predicate push is to make Oracle Filter out useless data as early as possible , To improve query performance .

More articles are welcome to follow my official account , search dbachongzi Or scan QR code

author : Yao Chong Oracle OCM、MySQL OCP、Oceanbase OBCA、PingCAP PCTA authentication , Good at based on Oracle、MySQL Performance Turning And a variety of relational NoSQL database .

原网站

版权声明
本文为[Yaochong]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/10/20211026185654986C.html