An example of mysql's limit paging query optimization through "delayed association"

Recently, I encountered a problem that paging query is very slow in production. The amount of data is about 2 million. The performance of turning to the last page is very low. It takes about 4 seconds to display the entire page. Query optimization is required.
The first step is to find the slow SQL, as follows:
SELECT
        hotel_id as hotelId,
mroom_type_id as mroomTypeId,
available_date as availableDate,
result_status as resultStatus,
create_time as createTime,
operate_time as operateTime
        FROM autofs_ivr
ORDER BY hotel_id
LIMIT 1983424, 20 Explain

:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE autofs_ivr ALL None None None None None 1875402 Using file sort

It can be seen that the type is all, and a full table scan is taken. Extra is using file sort, not index coverage.
The columns selected by the select statement are not in the order by column except hotel_id, and there is an index on the hotel_id column, so this sql does not go through index coverage. Every time a record is queried according to the secondary index, it has to go through it again. The primary key index goes to the table to find the other columns needed, which is naturally slow.

Is there any way to optimize this limit paging query? "High Performance MySQL" mentions a "delayed association" technology, which can optimize this sql. The optimized statement is as follows:
SELECT
        hotel_id as hotelId,
mroom_type_id as mroomTypeId,
available_date as availableDate,
result_status as resultStatus,
operate_time as operateTime,
create_time as createTime
        FROM autofs_ivr
        inner join(
        select id
        from autofs_ivr
        ORDER BY hotel_id
        LIMIT 1983424, 20
    ) as lim using(id));

explain the result as follows:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ALL None None None None 20
1 PRIMARY autofs_ivr eq_ref PRIMARY PRIMARY 4 lim.id 1
2 DERIVED autofs_ivr index None ix_sh_mr 124 None 1875402 Using

index 20 records are generated, and then the primary key is associated with the table itself. Even if a full table scan is performed, only 20 records are accessed, and the query time is reduced to 400 milliseconds, which is 10 times faster.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326562350&siteId=291194637