I have the following mysql query that I think should be faster. The database table has 1 million records and the query table 3.5 seconds
set @numberofdayssinceexpiration = 1;
set @today = DATE(now());
set @start_position = (@pagenumber-1)* @pagesize;
SELECT *
FROM (SELECT ad.id,
title,
description,
startson,
expireson,
ad.appuserid UserId,
user.email UserName,
ExpiredCount.totalcount
FROM advertisement ad
LEFT JOIN (SELECT servicetypeid,
Count(*) AS TotalCount
FROM advertisement
WHERE Datediff(@today,expireson) =
@numberofdayssinceexpiration
AND sendreminderafterexpiration = 1
GROUP BY servicetypeid) AS ExpiredCount
ON ExpiredCount.servicetypeid = ad.servicetypeid
LEFT JOIN aspnetusers user
ON user.id = ad.appuserid
WHERE Datediff(@today,expireson) = @numberofdayssinceexpiration
AND sendreminderafterexpiration = 1
ORDER BY ad.id) AS expiredAds
LIMIT 20 offset 1;
Here's the execution plan:
Here are the indexes defined on the table:
I wonder what I am doing wrong.
Thanks for any help
CodePudding user response:
First, I would like to point out some problems. Then I will get into your Question.
LIMIT 20 OFFSET 1gives you 20 rows starting with the second row.The lack of an
ORDER BYin the outer query may lead to an unpredictable ordering. In particular, the Limit and Offset can pick whatever they want. New versions will actually throw away theORDER BYin the subquery.DATEDIFF, being a function, makes that part of theWHEREnot 'sargeable'. That is it can't use anINDEX. The usual way (which is sargeable) to compare dates is (assumingexpiresonis of datatypeDATE):WHERE expireson >= CURDATE() - INTERVAL 1 DAYPlease qualify each column name. With that, I may be able to advise on optimal indexes.
Please provide
SHOW CREATE TABLEso that we can see what column(s) are in each index.
CodePudding user response:
WHERE Datediff()=...
mysql can't know where to start.Then he will scan the whole table to try every possibility


