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
OR
s 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 OR
s 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 join
is 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