Why does this query take 32 sec to execute?
-
10-12-2020 - |
Frage
I keep my history records in one table and my pertinent data in another. I want to grab only the files from myfiles
that currently have a given status recorded in statuses
(ie, the latest status is the one I want to filter by). I'm trying a subquery which may be a mistake, but I can't really think of another way to do it because there are many statuses for a given file in myfiles
.
MySQL 5.0.96, column schema on both tables involved is fewer than 15.
< 500 records in myfiles
, 68k records in statuses
:
SELECT myfiles.*,
(SELECT status FROM statuses WHERE statuses.itemtype=2 AND statuses.id=myfiles.id ORDER BY historyid DESC LIMIT 1) AS actualStatus
FROM myfiles
HAVING actualStatus=0
Here's a fiddle with the actual table schemas involved. Thank you!
Lösung 4
Just going to let you guys know what I did, thanks for responding. I ended up sticking with my original query but added keys to my table, which are apparently a thing I didn't know about. When I did
ALTER TABLE tblstatushistory
ADD KEY (id),
ADD KEY (itemtype)
It dropped the time waaaay down. Thanks for pointing me towards resources that taught me about EXPLAIN
(or at least explained EXPLAIN
) and about understanding indexes.
Andere Tipps
I'd actually think about adding a status column to the table tblstockingorders and having a trigger on that table that injects the status into the tblstatushistory.
Granted you'd have to do a 1-time update to all the rows in tblstockingorders (something similar to your query above) and set their last status, but this would give you best overall performance as these two tables grow.
Sounds like you want only the orders with a certain status/type...
SELECT tblstockingorders.*, tblstatushistory.status AS actualStatus
FROM tblstockingorders
INNER JOIN tblstatushistory
ON tblstatushistory.id=tblstockingorders.stockingorderid
WHERE tblstatushistory.itemtype=2
AND tblstatushistory.status=0
editted version
SELECT tblstockingorders.*, actualStatus.actualStatus
FROM tblstockingorders
INNER JOIN
(
SELECT ID, MAX(Status) AS actualStatus
FROM tblstatushistory
GROUP BY ID
) actualStatus
ON actualStatus.id=tblstockingorders.stockingorderid
WHERE tblstatushistory.itemtype=2
AND tblstatushistory.status=0