Scenario
The following two queries return the same results as desired.
The "SubmissionStatus" table is expected to grow to 100K+ rows
Query 1
SELECT field1, field2, ect...
FROM (SELECT *
FROM `Job1111`.SubmissionStatus ss
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (60,61,62,63,64,65,66,67,68,69,96)) ss
JOIN `Job1111`.SteelTrackerDetails std
ON std.BidID = ss.fk_BidIDAssigned
LEFT JOIN `Job1111`.SteelShake stls
ON ss.ActivityType = 61 AND ss.ActivityRowId = stls.ID
LEFT JOIN `Job1111`.SteelErect stle
ON ss.ActivityType = 62 AND ss.ActivityRowId = stle.ID
LEFT JOIN `Job1111`.SteelBoltOut stlb
ON ss.ActivityType = 63 AND ss.ActivityRowId = stlb.ID
LEFT JOIN `Job1111`.SteelImp stli
ON ss.ActivityType = 64 AND ss.ActivityRowId = stli.ID
LEFT JOIN `Job1111`.SteelWeld stlw
ON ss.ActivityType = 68 AND ss.ActivityRowId = stlw.ID
LEFT JOIN `Job1111`.SteelSell stlsell
ON ss.ActivityType = 65 AND ss.ActivityRowId = stlsell.ID
LEFT JOIN `Job1111`.SteelDemo stld
ON ss.ActivityType = 67 AND ss.ActivityRowId = stld.ID
LEFT JOIN `Job1111`.SteelMisc stlm
ON ss.ActivityType = 96 AND ss.ActivityRowId = stlm.ID
GROUP BY std.BidID
Query 2
SELECT field1, field2, ect...
FROM `Job1111`.SubmissionStatus ss
JOIN `Job1111`.SteelTrackerDetails std
ON std.BidID = ss.fk_BidIDAssigned
LEFT JOIN `Job1111`.SteelShake stls
ON ss.ActivityType = 61 AND ss.ActivityRowId = stls.ID
LEFT JOIN `Job1111`.SteelErect stle
ON ss.ActivityType = 62 AND ss.ActivityRowId = stle.ID
LEFT JOIN `Job1111`.SteelBoltOut stlb
ON ss.ActivityType = 63 AND ss.ActivityRowId = stlb.ID
LEFT JOIN `Job1111`.SteelImp stli
ON ss.ActivityType = 64 AND ss.ActivityRowId = stli.ID
LEFT JOIN `Job1111`.SteelWeld stlw
ON ss.ActivityType = 68 AND ss.ActivityRowId = stlw.ID
LEFT JOIN `Job1111`.SteelSell stlsell
ON ss.ActivityType = 65 AND ss.ActivityRowId = stlsell.ID
LEFT JOIN `Job1111`.SteelDemo stld
ON ss.ActivityType = 67 AND ss.ActivityRowId = stld.ID
LEFT JOIN `Job1111`.SteelMisc stlm
ON ss.ActivityType = 96 AND ss.ActivityRowId = stlm.ID
WHERE ss.fk_ActivityStatus IN (5,12)
AND ss.ActivityType IN (60,61,62,63,64,65,66,67,68,69,96)
GROUP BY std.BidID
Explain Select (per request)
id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'PRIMARY', '<derived12>', 'ref', '<auto_key0>', '<auto_key0>', '5', 'Job1111.std.BidID', '10', NULL
'12', 'DERIVED', 'ss', 'ALL', 'fk_SubmissionStatus_trackerDetails_idx,ActivityType,Combo_SSActivityStatus_ActivityType,Combo_SSActivityType_ActivityRowID', NULL, NULL, NULL, '347', 'Using where; Using temporary; Using filesort'
'12', 'DERIVED', 'stls', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'Job1111.ss.ActivityRowId', '1', 'Using where'
'12', 'DERIVED', 'stle', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'Job1111.ss.ActivityRowId', '1', 'Using where'
'12', 'DERIVED', 'stlb', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'Job1111.ss.ActivityRowId', '1', 'Using where'
'12', 'DERIVED', 'std', 'ref', 'BidID', 'BidID', '4', 'Job1111.ss.fk_BidIDAssigned', '1', NULL
'12', 'DERIVED', 'stli', 'ALL', 'PRIMARY', NULL, NULL, NULL, '3', 'Using where; Using join buffer (Block Nested Loop)'
'12', 'DERIVED', 'stlw', 'ALL', 'PRIMARY', NULL, NULL, NULL, '1', 'Using where; Using join buffer (Block Nested Loop)'
'12', 'DERIVED', 'stlsell', 'ALL', 'PRIMARY', NULL, NULL, NULL, '1', 'Using where; Using join buffer (Block Nested Loop)'
'12', 'DERIVED', 'stld', 'ALL', 'PRIMARY', NULL, NULL, NULL, '1', 'Using where; Using join buffer (Block Nested Loop)'
'12', 'DERIVED', 'stlm', 'ALL', 'PRIMARY', NULL, NULL, NULL, '1', 'Using where; Using join buffer (Block Nested Loop)'
'22', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'21', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'20', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'19', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'18', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'17', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'16', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'15', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'14', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'13', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'11', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'10', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'9', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'8', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'7', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'6', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'5', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'4', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'3', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
'2', 'SUBQUERY', 'SETTINGS', 'const', 'PRIMARY', 'PRIMARY', '98', 'const', '1', NULL
Show Create Table (per request)
'CREATE TABLE `SubmissionStatus` (
`PSAActivityID` int(11) NOT NULL AUTO_INCREMENT,
`fk_SubmissionId` int(11) DEFAULT NULL,
`ActivityType` tinyint(3) DEFAULT NULL,
`ActivityRowId` int(11) DEFAULT NULL,
`fk_BidIDAssigned` int(11) DEFAULT NULL,
`fk_ActivityStatus` int(11) DEFAULT ''1'',
`fk_LastModifiedBy` mediumint(8) unsigned DEFAULT NULL,
`LockField` mediumint(8) unsigned DEFAULT NULL,
`Rev` tinyint(3) unsigned NOT NULL DEFAULT ''0'',
`TimeStamp` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`PSAActivityID`),
KEY `fk_StatusSubmissionId_idx` (`fk_SubmissionId`),
KEY `fk_tblSubmissionStatus_tblUserPSA3_idx` (`fk_LastModifiedBy`),
KEY `fk_SubmissionStatus_trackerDetails_idx` (`fk_BidIDAssigned`),
KEY `TimeStamp` (`TimeStamp`),
KEY `ActivityType` (`ActivityType`),
KEY `Combo_SSActivityStatus_ActivityType` (`fk_ActivityStatus`,`ActivityType`),
KEY `Combo_SSActivityType_ActivityRowID` (`ActivityType`,`ActivityRowId`),
CONSTRAINT `fk_tblSubmissionStatus_tblSubDetails` FOREIGN KEY (`fk_SubmissionId`) REFERENCES `SubsDetails` (`SubmissionID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2455 DEFAULT CHARSET=utf8'
Question
After review the Explain output it got me thinking about how I was handling the initial call to table SubmissionStatus. But I'm not sure if moving the WHERE statement like I showed above makes a difference. Is one way better then the other?
Best Answer
Your first Query generates a temporary table, then reads it. The second one avoids these steps.
It is almost always better to avoid subqueries when you have a choice. It is less work for the Optimizer, and less work to execute the query.
(There are exceptions.)
This composite index is likely to help:
You have
LEFT
; does that mean you are expecting some of the 'right' queries to return nothing? If not, changingLEFT JOIN
toJOIN
often (again, there are exceptions) improves things.