MySQL Query Optimization Tips
Common SQL Optimization
Select only need columns
Convert a complex SQL statement to multiple simple SQL statements
Convert queries to use indexes. Using indexes operators: =, >, <, >=, <=, BETWEEN, IN. Not using indexes operators: LIKE, <>, NOT IN. Using MySQL built-in functions on column make query cannot use index.
NOT IN
Using LEFT JOIN or NOT EXISTS to replace NOT IN
A NOT IN query example
select * |
Use NOT EXISTS
select * |
Use LEFT JOIN
select * |
LIKE
Using Full-text search MATCH ... AGAINST... or search engine replace LIKE
OR
Using IN, or UNION, or AND NOT to replace OR
ORs are notoriously bad performers, because it splinters the execution path. The UNION alleviates that splintering, and the combines the two results sets. That said, IN is preferable to ORs because though being logically the same, the execution of IN is generally more optimized.
The OR query example 1:
select * |
Using IN
select * |
The OR query example 2:
select * |
Using UNION
select * |
The OR query example 3:
select * |
Using AND NOT
select * |
Built-in Functions
Avoid using functions in predicates
Use BETWEEN to replace DATE(), DATE_FORMAT()
A DATE_FORMAT example:
DATE_FORMAT(`date`, "%Y-%m") = "2022-07" |
YEAR(`date`) = "2022" and MONTH(`date`) = "7" |
Use BETWEEN
`date` BETWEEN '2022-07-01' and '2022-07-31' |
Convert function to use on right side
WHERE f(g(h(column))) > value |
WHERE column > H(G(F(value))) |
Page Query
Basic Optimization
- Query only the necessary columns instead of
select * - Query part of the TEXT column by
SUBSTR(column, start, length)if it could be.
High Offset Page Query Improvement
Late row lookups: Inner join ids instead of select *
Inner joinis first to find offset + size rows id, then find all rows data by id setselect *is just to find offset + size rows data.
select *
select * |
Inner join ids
select * |
In most cases, the inner join has a 5x performance improvement, but in some cases there is no difference in performance.
The performance gap is more evident for large row-width tables and queries with large offset.
Next Page Query Improvement
Specify start row id for next page query
first page query
select * |
next page query
select * |
Cache Page Query
- Caching total row number for the same condition queries.
- Caching every page start row id value and end row id value for the same condition queries.
References
General
Optimizing SELECT Statements - MySQL 8.0 Reference Manual
High Offset
MySQL ORDER BY / LIMIT performance: late row lookups
OR