简体   繁体   中英

How to optimise this MySQL query

I have the following MySQL query:

SELECT k.strNaam
FROM klant AS k
INNER JOIN project AS p ON p.iKlantID = k.iKlantID
LEFT JOIN klant_factuurregels AS kfr ON kfr.iJobID = p.iProjectID
WHERE p.iFactuurID =  '49'
OR kfr.iFactuurID =  '49'

This query takes more than 0.5 seconds to load, but I am using it in a while loop so that's very inefficient.

Thanks in advance

Edit the MySQL query with the EXPLAIN command prepended:

id  | select_type   | table | type  | possible_keys | key       | key_len           | ref                       | rows    | Extra
1     SIMPLE          p       ALL     iKlantID        NULL        NULL                NULL                        18848  
1     SIMPLE          k       eq_ref  PRIMARY         PRIMARY     8                   projecten.p.iKlantID        1  
1     SIMPLE          kfr     ALL     NULL            NULL        NULL                NULL                        18        Using where

Try if this one won't be faster... because of the or condition in the where clause, index cannot be used to resolve the WHERE. But the worst part is that the iKlantID index was not used to resolve the join.

SELECT k.strNaam
FROM klant AS k
INNER JOIN project AS p ON p.iKlantID = k.iKlantID
LEFT JOIN klant_factuurregels AS kfr ON kfr.iJobID = p.iProjectID
WHERE p.iFactuurID =  '49'
UNION 
SELECT k.strNaam
FROM klant AS k
INNER JOIN project AS p ON p.iKlantID = k.iKlantID
LEFT JOIN klant_factuurregels AS kfr ON kfr.iJobID = p.iProjectID
WHERE kfr.iFactuurID =  '49'

Speed issues
Put indexes on all fields involved in the joins.
And on iFactuurID .

Loops and SQL don't mix
Well they do, but slowness will be the result.

Instead try code like this.

$array = (10,11,12,13,49);
//if this comes from outside you need to sanitize these values 
//using PDO or mysql_real_escape_string
$in = "'".implode("','",$array)."'"; 
$sql = "SELECT k.strNaam
        FROM klant AS k
        INNER JOIN project AS p ON p.iKlantID = k.iKlantID
        LEFT JOIN klant_factuurregels AS kfr ON kfr.iJobID = p.iProjectID
        WHERE p.iFactuurID IN ($in)
        OR kfr.iFactuurID IN ($in) ";
$result = mysql_query($sql);
while ($row = mysql_fetch_row($result)) 
{
   //do stuff
}

If the values are consecutive, it's much faster to use

WHERE p.iFactuur BETWEEN '$lowvalue' AND '$highvalue' 

Always let SQL do the heavy lifting in loops.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM