Use limit to optimize queries and prevent SQL from being optimized


Table of Contents

  • Query optimization
    • 1.1 Optimization of maximum and minimum values
    • 1.2 Optimize limit paging
      • 1.2.1 Optimization using Associated Query
      • 1.2.2 Use range Query
      • 1.2.3 Query with unique increment sequence
  • Prevent being optimized
  • reference

Query optimization

1.1 Optimization of maximum and minimum values

MySQL is not optimized very well for MIN() and MAX() queries, for example

select MIN(id) FROM film where name = Journey to the West;Copy the code

Assume that the film data in the table is as follows:

id name price
1 hero 12
2 Which zha legend 14
3 Journey to the west 34
4 Water margin 23
5 A dream of red mansions 34
6 The red 2
7 The red 4
8 The little mermaid 23
9 Dad back 23
10 Who am I 12
11 Pleasant goat 56
12 Journey to the west 67

Where id is the primary key and is incremented, name is vARCHar and has no index

Because name has no index, because MySQL will perform a full table scan. Select * from ‘id’ where id =’ name ‘; select * from ‘id’;

select id FROM film where name = Journey to the West limit 1;Copy the code

When the first record is found, the query stops, achieving higher performance.

1.2 Optimize limit paging

When the system performs paging operations, when the offset is large, such as limit 1000020 and 20, MySQL needs to query 10020 records and only return 20 records, and all the previous records are discarded. This is very expensive

SELECT id, name, price FROM file LIMIT 10000 OFFSET 20
Copy the code

The SQL above I think is written in a regular way for pagination, which is nothing wrong and, as mentioned above, wastes a lot of performance.

1.2.1 Optimization using Associated Query

A simple way to optimize such queries is to use indexes to cover the scan as much as possible, rather than querying all columns, then doing an association as needed and returning the required columns. For large offsets, the efficiency gains are huge.

SELECT
    id, name, price
FROM film
INNER JOIN (
    SELECT id
    FROM film
    LIMIT 10000 OFFSET 20
    ) AS LIM USING(id)
Copy the code

1.2.2 Use range Query

LIMIT can sometimes be converted to a query for a known location, allowing MySQL to obtain the corresponding result through a range scan. For example, if there is an index on a positional column and the boundary values are precomputed, rewrite the query to:

SELECT id, name, price
FROM film
WHERE position BETWEEN 10000 AND 10020
ORDER BY position
Copy the code

1.2.3 Query with unique increment sequence

The only increment sequence here can be the increment ID primary key or any other number that has a unique and ascending order

In the previous thought, we are concerned with the number of pages and the number of pages per page. In some operations, we can pass in the increment sequence of the last query and then query the corresponding number of pages per page.

For example, the number of pages (pageIndex) and the number of pages (pageSize) are passed to the front end

select * from film 
limit (pageIndex - 1) * pageSize OFFSET pageIndex * pageSize
Copy the code

Instead, let the front end pass in the increment sequence (SID) and the number of pages per query (pageSize) for the last query.

For example, if sid is the id of film, then SQL can be rewritten to

select * from film 
where id > sid
limit pageSize
Copy the code

When the first page is checked, sid passes in 0, and when the second page is checked, sid gets the first page and finally gets the ID

Prevent being optimized

In addition to optimizing your SQL to reduce execution time, sometimes you need to prevent your SQL from being optimized for you by MySQL itself, resulting in execution results that are not what you expected.

When the group by statement is used in MySQL query, the first data is displayed when multiple values are met. For example:

Assume that the film data in the table is as follows:

id name price
1 hero 12
2 Which zha legend 14
3 Journey to the west 34
4 Water margin 23
5 Tang march 80
6 Tang march 50

SQL select * from film group by name

id name price
1 hero 12
2 Which zha legend 14
3 Journey to the west 34
4 Water margin 23
5 Tang march 80

But when some data is repeated, we tend to want the last item of data, which is what we would think through the form of sub-query first sorted after group by as follows:

select *
from ( select * from film order by id desc) as film_ordered
group by name;
Copy the code

The Derived table does not contain any of the following conditions:

  • UNION clause
  • GROUP BY
  • DISTINCT
  • Aggregation
  • LIMIT or OFFSET

According to the above description, we can use limit to prevent subquery optimization and rewrite the SQL

select *
from ( select * from film order by id desc limit 10000000) as film_ordered
group by name;
Copy the code

So that’s what we want

reference

Blog.csdn.net/lglaljj123/…