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:
- 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.
- Prefer Direct Join Over Joined Subquery (query line: 18): We advise against using subqueries as they are not optimized well by the optimizer. Therefore, we recommend to replace subqueries with JOIN clauses.
- Prefer Direct Join Over Joined Subquery (query line: 32): We advise against using subqueries as they are not optimized well by the optimizer. Therefore, we recommend to replace subqueries with JOIN clauses.
- Prefer Direct Join Over Joined Subquery (query line: 48): We advise against using subqueries as they are not optimized well by the optimizer. Therefore, we recommend to replace subqueries with JOIN clauses.
- Prefer Direct Join Over Joined Subquery (query line: 58): We advise against using subqueries as they are not optimized well by the optimizer. Therefore, we recommend to replace subqueries with JOIN clauses.
- Prefer Inner Join Over Left Join (modified query below): We identified that one or more left joined entities (e.g. `srt`) are used in the 'where' clause, in a way that allows to replace it with an optimized inner join. Inner joins can be fully optimized by the database, while Left joins apply limitations on the database's optimizer.
- Use Numeric Column Types For Numeric Values (query line: 7): Referencing a numeric value (e.g. 0) 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.
- Use Numeric Column Types For Numeric Values (query line: 9): Referencing a numeric value (e.g. 0) 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.
- Use Numeric Column Types For Numeric Values (query line: 13): Referencing a numeric value (e.g. 0) 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.
- Use Numeric Column Types For Numeric Values (query line: 30): Referencing a numeric value (e.g. 28) 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.
- Use Numeric Column Types For Numeric Values (query line: 31): Referencing a numeric value (e.g. 1) 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 `gebruikers` ADD INDEX `gebruikers_idx_groepsid_schoolcode` (`groepsid`,`schoolcode`);
ALTER TABLE `scores` ADD INDEX `scores_idx_userid` (`userid`);
ALTER TABLE `soorten` ADD INDEX `soorten_idx_verberg_soortid` (`verberg`,`soortid`);
ALTER TABLE `spellen` ADD INDEX `spellen_idx_spelid` (`spelid`);
ALTER TABLE `vakken` ADD INDEX `vakken_idx_vakid` (`vakid`);
The optimized query:
SELECT
u.achternaam AS achternaam,
u.code AS code,
srt.niveaus AS niveaus,
srt.soortid AS soortid,
IFNULL(scr.gehaald,
'0') AS gehaald,
IFNULL(scr.gespeeld,
'0') AS gespeeld,
IF(srt.niveaus = 1,
'n.v.t.',
IFNULL(scr.huidigniveau,
'0')) AS niveautext
FROM
gebruikers u
LEFT JOIN
scores scr
ON scr.userid = u.code
INNER JOIN
soorten srt
ON scr.soortid = srt.soortid
LEFT JOIN
spellen g
ON srt.spelid = g.spelid
LEFT JOIN
vakken vak
ON g.vakid = vak.vakid
WHERE
(
u.groepsid = '28'
AND u.schoolcode = '1'
AND srt.verberg = 0
)
AND (
srt.soortid IN (
13, 14, 15, 16, 17, 561, 566, 567, 568, 574, 575, 1, 100, 101, 102, 103, 104, 105, 107, 108, 109, 11, 110, 112, 113, 114, 115, 116, 117, 118, 12, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 133, 134, 137, 138, 140, 141, 144, 145
)
)
ORDER BY
u.achternaam,
vak.vaknaam,
g.spelnaam,
srt.titel ASC