For the query above, the following recommendations will be helpful as part of the SQL tuning process.
You'll find 3 sections below:
The optimization process and recommendations:
- Avoid Calling Functions With Indexed Columns (query line: 19): When a function is used directly on an indexed column, the database's optimizer won’t be able to use the index. For example, if the column `publishedon` is indexed, the index won’t be used as it’s wrapped with the function `YEARWEEK`. If you can’t find an alternative condition that won’t use a function call, a possible solution is to store the required value in a new indexed column.
- Avoid OFFSET In LIMIT Clause (query line: 34): OFFSET clauses can be very slow when used with high offsets (e.g. with high page numbers when implementing paging). Instead, use the following \u003ca target\u003d"_blank" href\u003d"http://www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-slow/"\u003eseek method\u003c/a\u003e, which provides better and more stable response rates.
- Create Optimal Indexes (modified query below): The recommended indexes are an integral part of this optimization effort and should be created before testing the execution duration of the optimized query.
- Use Numeric Column Types For Numeric Values (query line: 25): Referencing a numeric value (e.g. 64) as a string in a WHERE clause might result in poor performance. Possible impacts of storing numbers as varchars: more space will be used, you won't be able to perform arithmetic operations, the data won't be self-validated, aggregation functions like SUM won't work, the output may sort incorrectly and more. If the column is numeric, remove the quotes from the constant value, to make sure a numeric comparison is done.
Optimal indexes for this query:
ALTER TABLE `listings` ADD INDEX `listings_idx_cat_id_deleted_publish_id` (`cat_id`,`deleted`,`published`,`id`);
ALTER TABLE `listings` ADD INDEX `listings_idx_views` (`views`);
The optimized query:
SELECT
listings.id,
listings.type,
listings.source_id,
listings.link,
listings.short_link,
listings.cat_id,
listings.title,
listings.description,
listings.images,
listings.views,
listings.comments,
listings.published,
listings.publishedon
FROM
listings
WHERE
(
YEARWEEK(FROM_UNIXTIME(listings.publishedon), 1) = YEARWEEK(CURDATE(), 1)
)
AND (
listings.id != 88587
)
AND (
listings.cat_id = '64'
)
AND (
listings.deleted = 0
)
AND (
listings.published = 1
)
ORDER BY
listings.views DESC LIMIT 1 OFFSET 0