In some cases, MySQL can use an index to satisfy an
ORDER BY clause without doing any extra
sorting.
The index can also be used even if the ORDER
BY does not match the index exactly, as long as all of
the unused portions of the index and all the extra
ORDER BY columns are constants in the
WHERE clause. The following queries use the
index to resolve the ORDER BY part:
SELECT * FROM t1 ORDER BYkey_part1,key_part2,... ; SELECT * FROM t1 WHEREkey_part1=constantORDER BYkey_part2; SELECT * FROM t1 ORDER BYkey_part1DESC,key_part2DESC; SELECT * FROM t1 WHEREkey_part1=1 ORDER BYkey_part1DESC,key_part2DESC;
In some cases, MySQL cannot use indexes to
resolve the ORDER BY, although it still uses
indexes to find the rows that match the WHERE
clause. These cases include the following:
You use ORDER BY on different keys:
SELECT * FROM t1 ORDER BYkey1,key2;
You use ORDER BY on non-consecutive parts
of a key:
SELECT * FROM t1 WHEREkey2=constantORDER BYkey_part2;
You mix ASC and DESC:
SELECT * FROM t1 ORDER BYkey_part1DESC,key_part2ASC;
The key used to fetch the rows is not the same as the one
used in the ORDER BY:
SELECT * FROM t1 WHEREkey2=constantORDER BYkey1;
You are joining many tables, and the columns in the
ORDER BY are not all from the first
non-constant table that is used to retrieve rows. (This is
the first table in the EXPLAIN output
that doesn't have a const join type.)
You have different ORDER BY and
GROUP BY expressions.
The type of table index used doesn't store rows in order.
For example, this is true for a HASH
index in a HEAP table.
With EXPLAIN SELECT ... ORDER BY, you can
check whether MySQL can use indexes to resolve the query. It
cannot if you see Using filesort in the
Extra column. See Sección 7.2.1, “Sintaxis de EXPLAIN (Obtener información acerca de
un SELECT)”.
In MySQL 5.0, a filesort optimization is used
that records not only the sort key value and row position, but
the columns required for the query as well. This avoids reading
the rows twice. The filesort algorithm works
like this:
Read the rows that match the WHERE
clause, as before.
For each row, record a tuple of values consisting of the sort key value and row position, and also the columns required for the query.
Sort the tuples by sort key value
Retrieve the rows in sorted order, but read the required columns directly from the sorted tuples rather than by accessing the table a second time.
This algorithm represents an improvement over that used in some older versions of MySQL.
To avoid a slowdown, this optimization is used only if the total
size of the extra columns in the sort tuple does not exceed the
value of the max_length_for_sort_data system
variable. (A symptom of setting the value of this variable too
high is that you see high disk activity and low CPU activity.)
If you want to increase ORDER BY speed, first
see whether you can get MySQL to use indexes rather than an
extra sorting phase. If this is not possible, you can try the
following strategies:
Increase the size of the sort_buffer_size
variable.
Increase the size of the
read_rnd_buffer_size variable.
Change tmpdir to point to a dedicated
filesystem with large amounts of empty space. In MySQL 5.0,
this option accepts several paths that are used in
round-robin fashion. Paths should be separated by colon
characters (':') on Unix and semicolon
characters (';') on Windows, NetWare, and
OS/2. You can use this feature to spread the load across
several directories. Note: The paths
should be for directories in filesystems that are located on
different physical disks, not different
partitions on the same disk.
By default, MySQL sorts all GROUP BY
queries as if you
specified col1,
col2, ...ORDER BY in the query as
well. If you include an col1,
col2, ...ORDER BY clause
explicitly that contains the same column list, MySQL optimizes
it away without any speed penalty, although the sorting still
occurs. If a query includes GROUP BY but you
want to avoid the overhead of sorting the result, you can
suppress sorting by specifying ORDER BY NULL.
For example:
INSERT INTO foo SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.
