SQL slow query optimization join table query


I. Prerequisites #

1. Associated query##

The algorithm of MySQL table association is Nest Loop Join, which uses the result set of the driving table as the basic data of the loop, and then uses the data in the result set as the filter condition to query the data in the next table, and then merge the results.

2. Definition of drive table: ##

  • When the join condition is formulated, the drive table that satisfies the query condition with a small number of rows is the driving table;
  • When no join condition is specified, the table with fewer rows is the driving table. ( Emphasis!!! ).

The driving table can be sorted directly, and the non-driving table (field sorting) needs to sort the merged result (temporary table) of the loop query ( emphasis! ).

3. Explain result details:

Please refer to: http://blog.csdn.net/zhendong_Z/article/details/79363828

In the result of Explain, the table that appears in the first line is the driver table ( emphasis! !!! )

In the Explain result, if the id is the same, it can be considered as a group and executed sequentially from top to bottom; in all groups, the larger the id value, the higher the priority, and the earlier the execution.

Suggestion: If you
do n't know who should be the driver table and who should join who, please let MySQL run the judgment by itself .
The complex Nested Loop Join written by yourself is not very sure (as shown in the following example),
so don't specify who is left/right to join,
please leave it to the MySQL optimizer runtime to decide.
If you are especially confident in yourself, you can https://huoding.com/2013/06/04/261.

The goal of optimization is to reduce the number of loops of Nested Loop in JOIN as much as possible,
so as to ensure:
always use a small result set to drive a large result set (the key point of the circle!!! )

2. Case analysis:

1. The SQL statement is as follows:

`SELECT shipD.ID,shipD.SHIPMENT_NO,shipD.OUTBOUND_ID,shipD.OUTBOUND_NO,orderM.OUTBOUND_TYPE,
        orderM.OUTBOUNDSUB_TYPE,shipD.GOODS_VOLUMN,shipD.PACKING_UNIT,shipD.PACKING_QTY,shipD.PICKTASK_ID,
        shipD.TASK_TYPE,。。。orderM.dest_warehouse_no,orderM.dest_distribute_no,orderM.dest_org_no
FROM
OB_INTERNAL_SHIP_M shipM
JOIN OB_INTERNAL_SHIP_D shipD ON shipD.shipment_no = shipM.shipment_no
AND shipM.ORG_NO = shipD.ORG_NO
AND shipM.warehouse_no = shipD.WAREHOUSE_NO
JOIN OB_INTERNAL_ORDER_M orderM ON shipD.outbound_no = orderM.outbound_no
WHERE
shipM.BILL_NO = 'CD117090620'
AND shipM.HAND_NO = '43017090603370789'
AND shipD.ORG_NO = '4'
AND shipD.DISTRIBUTE_NO = '4'
AND shipD.WAREHOUSE_NO = '30'`

Explain result:

Picture (can't upload temporarily)

Existing indexes on the table:

`ob_internal_ship_m:  KEY `idx_update_time` (`UPDATE_TIME`),  KEY ‘idx_SHIPMENT_NO’ (‘SHIPMENT_NO’)

ob_internal_ship_d:   KEY `idx_update_time` (`UPDATE_TIME`),  KEY `idx_unique_key` (`UNIQUE_KEY`)   KEY ‘idx_SHIPMENT_NO’ (‘SHIPMENT_NO’),  KEY ‘idx_BOX_NO’(‘BOX_NO’)

ob_internal_order_m:  UNIQUE KEY `OB_INTERNAL_ORDER_m_index` (`OUTBOUND_NO`),  KEY `idx_update_time` (`UPDATE_TIME`),  KEY’idx_outbound_no’(‘OUTBOUND_NO’), KEY’idx_WAVE_NO’(‘WAVE_NO’), KEY’idx_OPRATE_STATUS’(‘OPRATE_STATUS’)`

Solutions:

In the joint query, if the conditions behind on are not satisfied, a full table query may occur, and there is no shipment_no in the where query condition. Determine whether the shipment_no satisfies the query. If not, consider adding the bill_no and hand_no in the existing where condition to the index.

The final proposal:

idx_bill_noThere are two uses of this sql statement in the business code, one of which cannot obtain the shipment_no, so add the KEY ( BILL_NO), KEY idx_hand_no( ) to the shipment_m table by adding an index HAND_NO.

2. The SQL statement is as follows:

`SELECT DISTINCT
    (waveM.wave_no)
FROM
    OB_INTERNAL_WAVE_M waveM
LEFT JOIN OB_INTERNAL_ORDER_M orderM ON waveM.wave_no = orderM.wave_no
WHERE
    waveM.YN = N
AND waveM.ORG_NO = 'S'
AND waveM.DISTRIBUTE_NO = 'S'
AND waveM.WAREHOUSE_NO = 'S'
AND waveM.OUTBOUND_TYPE = 'S'
AND waveM.WAVE_TYPE = 'S'
AND waveM.WAVE_STATUS = N
AND orderM.outboundsub_type IN ('S', 'S', 'S')
ORDER BY
waveM.CREATE_TIME DESC`

Explain result:

Picture (can't upload temporarily)

Existing indexes on the table:

`ob_internal_order_m:  UNIQUE KEY `OB_INTERNAL_ORDER_m_index` (`OUTBOUND_NO`),  KEY `idx_update_time` (`UPDATE_TIME`),  KEY’idx_outbound_no’(‘OUTBOUND_NO’), KEY’idx_WAVE_NO’(‘WAVE_NO’), KEY’idx_OPRATE_STATUS’(‘OPRATE_STATUS’)

ob_internal_wave_m:   KEY `idx_update_time` (`UPDATE_TIME`),  KEY `idx_wave_no` (`WAVE_NO`),  KEY `idx_wave_type` (`WAVE_TYPE`),  KEY `idx_source` (`SOURCE`),  KEY ’WAVE_STATUS’(‘WAVE_STATUS’)`

Solutions:

Determine whether the business logic needs to sort the SQL, remove the distinct deduplication, and do the deduplication in the business layer.

The final proposal:

There is no need to sort in the business, remove the order by, remove the distinct in the sql, and do the deduplication in the business layer. (If ordering is required in the business, consider updating_time or the primary key id in the wave_m table as the order by condition)

PS: Removing distinct can solve the problem of Using temporary temporary table, and removing order by or using update_time or id can solve the problem of Using filesort.

3. Summary:

Don't put too much faith in the execution speed of SQL in the production environment. Observe more SQL statements with slow execution efficiency, and don't just look at the instantaneous execution time. When using Explain, please pay attention to optimization in the following common situations:

  • type appears ALL or index;
  • possible_keys appears too many (to be selected) indexes;
  • The key is NULL (no index is taken);
  • There are too many rows, or almost the number of records in the entire table;
  • Using temporary appears in Extra, (Using filesort depends on the situation);

illustrate:

The type is ALL or index. The worst case of all is full table lookup. Index is the same as full table scan. Just scan the table in index order instead of row. The main advantage is that sorting is avoided, but the overhead is still very high. If you see Using index in the Extra column, it means that a covering index is being used, and only the indexed data is scanned, which is much less expensive than a full table scan in index order.

Using temporary, using temporary tables to save intermediate results, is often used in GROUP BY and ORDER BY operations. Generally speaking, it means that the query needs to be optimized. Even if the use of temporary tables cannot be avoided, the use of hard disk temporary tables should be avoided as much as possible.

Using filesort, MySQL has two ways to generate ordered results, through sorting operations or using indexes. When Using filesort appears in Extra, it means that MySQL uses the latter, but note that although it is called filesort, it does not mean that it uses files to Sorting is done in memory whenever possible. In most cases, it is faster to use the index to sort, so generally consider optimizing the query at this time. The sorting operation is done using the file, which may be the result of an ordery by, group by statement, which may be a CPU-intensive process, and performance can be improved by selecting an appropriate index, which is used to sort query results.

The general idea of ​​daily SQL optimization:

  • Use Explain to determine whether the above situation needs to be optimized;
  • Clarify the business logic corresponding to the SQL (such as: why it is written like this, whether the change will affect the existing business, whether the change at the business layer is feasible, etc.);
  • Whether the existing conditions can meet the optimization requirements (such as existing indexes, etc.);
  • When the above methods cannot meet the existing optimization requirements, finally consider whether to change the existing table structure (such as adding an index, etc.).

In short, SQL optimization is a complex process that requires slow work and meticulous work. The truth of which requires us to accumulate and gradually advance.

References:

https://www.cnblogs.com/zhengyun_ustc/p/slowquery1.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324811239&siteId=291194637