![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| ||||
| ||||
|
|
id | select_type | table | type | possible_keys | key | key_len | ref | |
|
1 | SIMPLE | addresses | ALL | NULL | NULL | NULL | NULL | 103391 | Using filesort | |
|
Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+----------------+ id | int(11) | NO | PRI | NULL | auto_increment | address | varchar(255) | YES | MUL | NULL | | header | int(11) | YES | MUL | NULL | | kind | varchar(512) | YES | | NULL | | +---------+--------------+------+-----+---------+----------------+ |
|
addresses | CREATE TABLE `addresses` ( `id` int(11) NOT NULL AUTO_INCREMENT, |
#2
| |||
| |||
|
|
Query is "select * from addresses order by address limit 1000 offset 90000" runs very slowly. |
|
mysql> explain select * from addresses order by address; +----+-------------+-----------+------+---------------+------+--------- +------+- -------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+------+---------------+------+--------- +------+- -------+----------------+ | 1 | SIMPLE | addresses | ALL | NULL | NULL | NULL | NULL | 103391 | Using filesort | +----+-------------+-----------+------+---------------+------+--------- +------+- -------+----------------+ |
#3
| ||||||
| ||||||
|
|
SergeyPo <ffvan... (AT) gmail (DOT) com> wrote: Query is "select * from addresses order by address limit 1000 offset 90000" runs very slowly. What is "very slowly"? Are you aware that ORDER BY ... LIMIT 90000,1000 has to read and sort 91000 rows anyway? mysql> explain select * from addresses order by address; +----+-------------+-----------+------+---------------+------+--------- +------+- -------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+------+---------------+------+--------- +------+- -------+----------------+ | 1 | SIMPLE | addresses | ALL | NULL | NULL | NULL | NULL | 103391 | Using filesort | +----+-------------+-----------+------+---------------+------+--------- +------+- -------+----------------+ Totally expected. You have 103000 rows in that table. The query has to read all of them. No use for any index. The table scan + sort is very probably faster than 103000 random row reads from that table. Of course, if your query would be SELECT address FROM addresses ORDER BY address then MySQL could use a covering index read (don't read any row from the table, but get all data from the index only). Since this is InnoDB, you could even use SELECT address, id ... But have you tried the EXPLAIN for SELECT ... LIMIT 90000,1000? Now it should use a range scan on the index, skipping the first 90000 index records and then 1000 random row reads. It /could/ be worth trying to rewrite the query like so: SELECT * FROM addresses t1 JOIN (SELECT id FROM addresses ORDER BY address LIMIT 90000,1000) t2 ON t1.id=t2.id (or alternatively as subquery with IN) Here the subquery could use the covering index and the outer would use the PK to refer result rows. XL |
|
id | select_type | table | type | possible_keys | key | key_len ref |rows | Extra | +----+-------------+-----------+------+---------------+------+--------- |
|
1 | SIMPLE | addresses | ALL | NULL | NULL | NULL NULL |103391 | Using filesort | +----+-------------+-----------+------+---------------+------+--------- |
|
id | select_type | table | type | possible_keys | key key_len | ref | rows | Extra | +----+-------------+-----------+-------+---------------+--------------- |
|
1 | SIMPLE | addresses | index | NULL | idx_addresses 768 | NULL | 91000 | Using index | +----+-------------+-----------+-------+---------------+--------------- |
|
id | address | header | kind | +-------+--------------------+--------+-----------------------+ 90001 | 000000000000000000 | 135287 | AMR_FULL_TRANSLIT | 90002 | 000000000000000000 | 135287 | ADDRESS_FULL_TRANSLIT | 90003 | 000000000000000000 | 135288 | AMR_FULL_TRANSLIT | 90004 | 000000000000000000 | 135288 | ADDRESS_FULL_TRANSLIT | 90005 | 000000000000000000 | 135289 | AMR_FULL_TRANSLIT | 90006 | 000000000000000000 | 135289 | ADDRESS_FULL_TRANSLIT | 90007 | 000000000000000000 | 135290 | AMR_FULL_TRANSLIT | 90008 | 000000000000000000 | 135290 | ADDRESS_FULL_TRANSLIT | 90009 | 000000000000000000 | 135291 | AMR_FULL_TRANSLIT | 90010 | 000000000000000000 | 135291 | ADDRESS_FULL_TRANSLIT | ...... |

#4
| ||||
| ||||
|
|
mysql> explain select * from addresses order by address limit 1000 offset 90000; +----+-------------+-----------+------+---------------+------+--------- +------+--------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref |rows | Extra | +----+-------------+-----------+------+---------------+------+--------- +------+--------+----------------+ | 1 | SIMPLE | addresses | ALL | NULL | NULL | NULL | NULL |103391 | Using filesort | +----+-------------+-----------+------+---------------+------+--------- +------+--------+----------------+ still no index is being used. If I run this select in console, it took 4.92 sec. |
|
If, as you suggested, I explicitly select some fields, it seems better: mysql> explain select address, id from addresses order by address limit 1000 off set 90000; +----+-------------+-----------+-------+---------------+--------------- +---------+------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+-------+---------------+--------------- +---------+------+-------+-------------+ | 1 | SIMPLE | addresses | index | NULL | idx_addresses | 768 | NULL | 91000 | Using index | +----+-------------+-----------+-------+---------------+--------------- +---------+------+-------+-------------+ This one runs 1.75 sec. This is great progress but for my app I need all fields in the result set. When I try to add any other field to SELECT, it stops using the index. |
|
I tried the following query: mysql> select * from addresses where addresses.id in (select id from addresses order by address) limit 1000 offset 90000; |
|
1000 rows in set (0.36 sec) but this gives wrong result |
![]() |
| Thread Tools | |
| Display Modes | |
| |