Two types of temporary tables in MySQL

Source: Internet
Author: User
Tags mysql manual scalar

Two types of temporary tables in MySQLbole Online 2016-07-06 05:16:52 Read (4556) Comments (3) Statement: This article by the Sohu public platform to write the author, in addition to the official Sohu account, the view is only representative of the author himself, does not represent the position of Sohu. Report

  External temp Table

Temporary tables created from the Create temporary table, which are called external temporary tables. This temporary table is visible only to the current user, and the temporary table is closed automatically when the current session ends. The name of this temporary table can have the same name as a non-temporal table (after the same name, non-temporary tables will not be visible to the current session until the temporary table is deleted).

  Internal temp Table

The internal temp table is a special lightweight temporary table for performance optimization. This temporary table is automatically created by MySQL and used to store intermediate results for some operations. These operations may be included in the optimization phase or the execution phase. This internal table is not visible to the user, but through explain or show status you can see if MySQL uses an internal temporary table to help with an operation. Internal temporal tables play a very important role in the optimization of SQL statements, and many of the operations in MySQL depend on internal temporal tables for optimization. However, the use of internal temporary tables requires the creation of tables and the access cost of intermediate data, so users should try to avoid using temporary tables when writing SQL statements.

There are two types of internal temporal tables: one is the heap staging table, all the data for this temporary table is in memory, and the operation of this table does not require IO operations. The other is the Ondisk temporary table, which, as its name implies, stores the data on disk. Ondisk temporary tables are used to handle intermediate results that are larger than the operation. If the heap temporary table stores more data than max_heap_table_size (refer to the System Variables section of the MySQL Manual for details), the heap temporary tables will be automatically converted to ondisk temporary tables. The Ondisk temp table can be selected using the MyISAM engine or InnoDB engine in 5.7 via the internal_tmp_disk_storage_engine system variable.

This article focuses on what operations might take advantage of internal temporary tables. If the user can write SQL statements with minimal use of internal temporary tables for query optimization, it will effectively improve the efficiency of query execution.

First we define a table T1,

CREATE TABLE T1 (a int, b int); INSERT into T1 VALUES (3,4);

All of the following actions are examples based on table T1.

Use sql_buffer_result hint in SQL statements

Sql_buffer_result is primarily used to allow MySQL to release the lock on the table as early as possible. Because if the amount of data is large, it takes a long time to send the data to the client, which effectively reduces the time it takes to read the lock on the table by buffering the data into the temporary table.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Mysql>explain Format=json Select Sql_buffer_result *from t1;

EXPLAIN

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "2.00"

},

"Buffer_result": {

"Using_temporary_table": true,

"Table": {

"table_name": "T1",

"Access_type": "All",

...

If the SQL statement contains derived_table.

In 5.7, with a new optimization approach, we need to use set optimizer_switch= ' Derived_merge=off ' to disallow derived table from merging into the outer query.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Mysql>explain Format=json Select *from (select *from t1) Astt;

EXPLAIN

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "2.40"

},

"Table": {

"table_name": "TT",

"Access_type": "All",

...

"Materialized_from_subquery": {

"Using_temporary_table": true,

...

If we query the system tables, the data from the system tables will be stored in the internal temporary table.

We are not currently able to use explain to see if the system table data needs to be exploited into an internal temporary table, but you can see whether the internal temporary table is being exploited through show status.

For example:

1

2

Mysql>select *from information_schema.character_sets;

Mysql>show status like ' create% ';

If the distinct statement is not optimized, that is, if the distinct statement is optimized for a group by operation or a unique index is used to eliminate distinct, the internal temporary table will be used.

1

2

3

4

5

6

7

8

9

10

11

12

Mysql>explain Format=json Select Distinctafrom T1;

EXPLAIN

{

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "1.60"

},

"Duplicates_removal": {

"Using_temporary_table": true,

...

If the query has an ORDER BY statement, it cannot be optimized. The following scenarios use the internal temporary table to cache intermediate data and then sort the intermediate data.

1) If the connection table uses BNL (batched nestloop)/bka (batched Key Access)

For example:

1) BNL is turned on by default

1

2

3

4

5

6

7

8

9

10

11

Mysql>explain Format=json Select *from t1,t1 ast2 order by t1.a;

EXPLAIN

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "22.00"

},

"Ordering_operation": {

"Using_temporary_table": true,

...

2) After you turn off BNL, ORDER by will use Filesort directly.

1

2

3

4

5

6

7

8

9

10

11

12

13

Mysql>set optimizer_switch= ' Block_nested_loop=off ';

Query ok,0rows Affected (0.00SEC)

Mysql>explain Format=json Select *from t1,t1 ast2 order by t1.a;

EXPLAIN

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "25.00"

},

"Ordering_operation": {

"Using_filesort": true,

...

2) The column for ORDER by does not belong to the column of the first join table in the execution plan.

For example:

1

2

3

4

5

6

7

8

9

10

11

Mysql>explain Format=json Select *fromtast1,tast2 Order by t2.a;

EXPLAIN

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "25.00"

},

"Ordering_operation": {

"Using_temporary_table": true,

...

3) If the expression for order by is a complex expression.

So what kind of order by expression does MySQL think is a complex expression?

1)) If the sort expression is SP or UDF.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21st

Drop functionifexists func1;

delimiter|

Create FUNCTIONFUNC1 (Xint)

Returns intdeterministic

Begin

DECLAREZ1,Z2 int;

Set z1=x;

Set z2=z1+2;

RETURNZ2;

end|

Delimiter

Explain Format=json select *from T1 ORDER by func1 (a);

{

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "2.20"

},

"Ordering_operation": {

"Using_temporary_table": true,

...

2)) The column of ORDER by contains the aggregate function

  To simplify the execution plan, we use index to refine the group by statement.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

CREATE index idx1 on T1 (a);

Explain Format=json selectafrom T1 group Byaorder by SUM (a);

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "1.20"

},

"Ordering_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

"Grouping_operation": {

"Using_filesort": false,

...

Drop index idx1 on T1;

3) The ORDER by column contains scalar subquery, and of course the scalar subquery is not optimized.

For example:

1

2

3

4

5

6

7

8

9

10

11

Explain Format=json Select (select rand () from T1 limit1) asafrom T1 order bya;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "1.20"

},

"Ordering_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

...

4) If the query has both an order by and a group by statement, the two statements use different columns.

Note: If it is 5.7, we need to set the Sql_mode to non-only_full_group_by mode, otherwise it will error.

  Also to simplify the execution plan, we use index to refine the group by statement.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Set sql_mode= ";

CREATE index idx1 on T1 (b);

Explain Format=json select T1.afrom T1 GROUP by T1.border By1;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "1.40"

},

"Ordering_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

"Grouping_operation": {

"Using_filesort": false,

...

Drop index idx1 on T1;

If the query has a GROUP BY statement, it cannot be optimized. The following scenarios use the internal temporary table to cache intermediate data and then group by for intermediate data.

1) If the connection table uses BNL (batched nestloop)/bka (batched Key Access).

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

Explain Format=json Select T2.afrom t1,t1 ast2 GROUP by t1.a;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "8.20"

},

"Grouping_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

"Cost_info": {

"Sort_cost": "4.00"

...

2) If the Group by column does not belong to the first join table in the execution plan.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

Explain Format=json Select T2.afrom t1,t1 ast2 GROUP by t2.a;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "8.20"

},

"Grouping_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

"Nested_loop": [

...

3) If the group BY statement uses a different column than the column used by the order by statement.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Set sql_mode= ";

Explain Format=json select T1.afrom T1 GROUP by T1.border by t1.a;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "1.40"

},

"Ordering_operation": {

"Using_filesort": true,

"Grouping_operation": {

"Using_temporary_table": true,

"Using_filesort": false,

...

4) If group by IS with rollup and is based on a multi-sheet outer join.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Explain Format=json select sum (t1.a) from T1 left joins T1 ast2 on Truegroup by T1.awith Rollup;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "7.20"

},

"Grouping_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

"Cost_info": {

"Sort_cost": "4.00"

},

...

5) If the group BY statement uses a column that is derived from the scalar subquery, and is not optimized.

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Explain Format=json Select (select AVG (a) from T1) Asafrom T1 group Bya;

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "3.40"

},

"Grouping_operation": {

"Using_temporary_table": true,

"Using_filesort": true,

"Cost_info": {

"Sort_cost": "2.00"

},

...

The in expression is converted to Semi-join for optimization

1) If Semi-join is executed as materialization

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Set optimizer_switch= ' Firstmatch=off,duplicateweedout=off ';

Explain Format=json select *from T1 whereain (selectbfrom t1);

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "5.60"

},

"Nested_loop": [

{

"Rows_examined_per_scan": 1,

"Materialized_from_subquery": {

"Using_temporary_table": true,

"Query_block": {

"Table": {

"table_name": "T1",

"Access_type": "All",

...

2) If Semi-join is executed as duplicate weedout

For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

Set optimizer_switch= ' Firstmatch=off ';

Explain Format=json select *from T1 whereain (selectbfrom t1);

| {

"Query_block": {

"select_id": 1,

"Cost_info": {

"Query_cost": "4.80"

},

"Duplicates_removal": {

"Using_temporary_table": true,

"Nested_loop": [

{

...

If the query statement with UNION,MYSQL will take advantage of the internal temporary table to help the Union Operation de-duplicates.

For example:

1

2

3

4

5

6

7

Explain Format=json select *from T1 Union select *from T1;

| {

"Query_block": {

"Union_result": {

"Using_temporary_table": true,

"table_name": "",

...

If the query statement uses multiple table updates.

Here explain cannot see the internal temporary table being exploited, so you need to see the status.

For example:

1

2

Update t1,t1 ast2 set t1.a=3;

Show status like ' create% ';

If the aggregate function contains the following function, the internal temporary table is also exploited.

1

2

3

4

5

6

1) count (DISTINCT *)

For example:

Explain Format=json select COUNT (distincta) from T1;

2) Group_concat

For example:

Explain Format=json select Group_concat (b) from T1;

In summary, there are 10 cases listed above, MySQL will use internal temporary table for intermediate result cache, if the amount of data is large, the internal temporary table will store the data on disk, which will obviously affect the performance. In order to reduce the performance loss as much as possible, we need to avoid this situation as much as possible.

Two types of temporary tables in MySQL

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.