From: "Scott Gifford"

>     mysql> explain
>       SELECT mirealsource_homes.mls_num,
>              mirealsource_homes_supplemental.listdate,
>              mirealsource_images.image1,
>              mirealsource_homes_stats.detail_views
>         FROM mirealsource_homes,
>              mirealsource_homes_supplemental
>              LEFT JOIN mirealsource_images
>                ON mirealsource_homes.mls_num =
>       mirealsource_images.mls_num
>              LEFT JOIN mirealsource_homes_stats
>                ON mirealsource_homes.mls_num =
>       mirealsource_homes_stats.mls_num
>        WHERE
>          mirealsource_homes.mls_num =
>       mirealsource_homes_supplemental.mls_num
>        ORDER BY mirealsource_homes.mls_num
>        LIMIT 1;
>
>
+----+-------------+---------------------------------+--------+-------------
--+---------+---------+-----------------------------------------------+-----
-+---------------------------------+
> | id | select_type | table                           | type   |
> possible_keys | key     | key_len | ref
> | rows | Extra        |
>
+----+-------------+---------------------------------+--------+-------------
--+---------+---------+-----------------------------------------------+-----
-+---------------------------------+
> |  1 | SIMPLE      | mirealsource_homes_supplemental | ALL    |
> PRIMARY       | NULL    |    NULL | NULL
> |  100 | Using temporary; Using filesort |
> |  1 | SIMPLE      | mirealsource_homes              | eq_ref |
> PRIMARY       | PRIMARY |       8 |
> devel.mirealsource_homes_supplemental.mls_num |    1 |        |
> |  1 | SIMPLE      | mirealsource_images             | eq_ref |
> PRIMARY       | PRIMARY |       8 | devel.mirealsource_homes.mls_num
> |    1 |        |
> |  1 | SIMPLE      | mirealsource_homes_stats        | eq_ref |
> PRIMARY       | PRIMARY |       8 | devel.mirealsource_homes.mls_num
> |    1 |        |
>
+----+-------------+---------------------------------+--------+-------------
--+---------+---------+-----------------------------------------------+-----
-+---------------------------------+
>
> Apparently MySQL's optimizer sees that it can use the primary key for
> mirealsource_home_supplemental to do the query, but for some reason
> decides not to.

This is often the case when the query will probably return more than 30% of
the records in that table. In such cases it is more efficient to do a full
table scan (which is indicated here by the 'ALL' type in the explain
output).

> I can fix the problem by requiring a STRAIGHT_JOIN, or by sorting by
> "mirealsource_homes_supplemental.mls_num" instead.  However, this
> query is part of a larger framework that handles a wide variety of
> queries, so I need to understand why this is happening instead of
> tweaking individual cases.

Furthermore MySQL can only use an index for sorting if all columns in the
ORDER BY clause are from the first table in the explain output that doesn't
have a 'const' join type. This is why setting the ORDER BY to
mirealsource_homes_supplemental.mls_num will remove the 'Using filesort' and
result in faster sorting.

MySQL tries to optimize queries by (among others) guestimating which path
will result in the smallest number of records. It appears that this path
with 100 * 8 * 8 * 8 (51200) records is the minimum size it can achieve.
You can use USE INDEX to (strongly) suggest the use of an index to MySQL and
see if it speeds up the query. Using  FORCE INDEX will tell MySQL that a
full table scan is very expensive, so this will make it extremely unlikely
that it will not use the index.

The optimizer often seems to gues 'wrong' in terms of speed. I put a USE
INDEX in a query and consequently the guessed number of records was
increased from around 1000 to over 2000, but since it could now use the
index to sort the result set the query was way faster in the end.

In this query you want the data where mls_num is as small as possible. Is
there a way you can limit the number of records by using an extra where
condition? This way you may change the order of the tables and make the
query faster.

I would also move the current WHERE condition to an ON condition in the FROM
part as it is not meant to limit the selected records, but as a definition
on how to join the two tables.

Regards, Jigal.


-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to