* Maximo Migliari
> Im running the following query:
>
> SELECT
>       user.nickname,
>       user.id,
>       user_detail.points
> FROM
>       user,
>       user_detail
> WHERE
>       user.details = user_detail.id
>       AND user.id > 101
>       AND user.language = 'en'
> ORDER BY user_detail.points DESC
> LIMIT 5;
[...]
> This is the result of the EXPLAIN for the query:
>
> +-------------+-------+-----------------------------+---------+---
> ------+----------------+-------+-----------------------------------------+
> | table       | type  | possible_keys               | key     | key_len |
> ref            | rows  | Extra                                   |
> +-------------+-------+-----------------------------+---------+---
> ------+----------------+-------+-----------------------------------------+
> | user_detail | range | PRIMARY,id,points           | points  |       4 |
> NULL           | 15567 | where used; Using index; Using filesort |
> | user        | ref   | PRIMARY,id,details,language | details |       4 |
> user_detail.id |     1 | where used                              |
> +-------------+-------+-----------------------------+---------+---
> ------+----------------+-------+-----------------------------------------+
>
> Someone told me that Using filesort is not a good sign... how can
> I improve
> the performace of this query? Any other tuning suggestions?

The EXPLAIN shows that the 'user_detail' table is read first, using the
'points' index. Approximately 15567 rows must be examined, and then the
'details' index of the 'user' table is used to do a lookup for each
'user_detail'.

Try using STRAIGHT_JOIN:

SELECT
  user.nickname,
  user.id,
  user_detail.points
FROM
  user STRAIGHT_JOIN
  user_detail
WHERE
  user.details = user_detail.id
  AND user.id > 101
  AND user.language = 'en'
ORDER BY user_detail.points DESC
LIMIT 5;

This will force mysql to read the user table first, probably using the
'language' index or the 'id' index, and then do a lookup on the
'user_detail' table. Because both tables have the approximate same number of
records (32.000) in this case, and the criteria "id > 101 AND language =
'en'" probably matches most of the users, it may not help much. But it is
worth a try.

If most of the rows in the 'user_detail' table are relavant to this query
(i.e. few users with id <= 101 and/or language<>'en') you may want to try a
different approach: select the 10 (or so) highest points from 'user_details'
first, then join with the 'user' table in a separate query:

CREATE TEMPORARY TABLE tmp1
SELECT user_detail.id,
  user_detail.points
FROM
  user_detail
ORDER BY points DESC
LIMIT 10;

SELECT
  user.nickname,
  user.id,
  tmp1.points
FROM
  tmp1 STRAIGHT_JOIN user
WHERE
  user.details = tmp1.id
  AND user.id > 101
  AND user.language = 'en'
ORDER BY points DESC
LIMIT 5;

HTH,

--
Roger


---------------------------------------------------------------------
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/           (the list archive)

To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php

Reply via email to