mysql> select range.id_country from address join range on address.address between range.begin_num and range.end_num; mysql> describe address; +---------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+------------------+------+-----+---------+-------+ | address | int(10) unsigned | YES | | NULL | | +---------+------------------+------+-----+---------+-------+ mysql> describe range; +-------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+---------------------+------+-----+---------+-------+ | begin_num | int(10) unsigned | NO | PRI | | | | end_num | int(10) unsigned | YES | UNI | NULL | | | id_country | tinyint(3) unsigned | YES | MUL | NULL | | +-------------+---------------------+------+-----+---------+-------+Both tables are MyISAM type. Table `address` is 2124 rows (all distinct). Table `range` is 105920 rows (all distinct).
ORDER BY ip_address DESCshould be:
ORDER BY start DESCHere is MySQL's explanation of the original query:
mysql> explain select range.id_country from address join range on address.address between range.begin_num and range.end_num; +----+-------------+---------+------+-----------------+------+---------+------+--------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+-----------------+------+---------+------+--------+------------------------------------------------+ | 1 | SIMPLE | address | ALL | NULL | NULL | NULL | NULL | 2124 | | | 1 | SIMPLE | range | ALL | PRIMARY,end_num | NULL | NULL | NULL | 105920 | Range checked for each record (index map: 0x7) | +----+-------------+---------+------+-----------------+------+---------+------+--------+------------------------------------------------+Here is PostgreSQL's explanation of the original query:
postgresql# explain select range.id_country from address join range on address.address between range.begin_num and range.end_num;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------
Nested Loop (cost=5.72..7061709.90 rows=83990942 width=2)
-> Seq Scan on range (cost=0.00..3316.47 rows=185547 width=18)
-> Bitmap Heap Scan on address (cost=5.72..31.25 rows=453 width=8)
Recheck Cond: ((address.address >= "outer".begin_num) AND (address.address <= "outer".end_num))
-> Bitmap Index Scan on addresses_pkey (cost=0.00..5.72 rows=453 width=0)
Index Cond: ((address.address >= "outer".begin_num) AND (address.address <= "outer".end_num))
Here is MySQL's explanation showing that a simple query can use the index on begin_num in a "range" type query plan:
mysql> explain select id_country from range where 123123123 between begin_num and end_num; +----+-------------+---------+-------+-----------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+-------+-----------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | range | range | PRIMARY,end_num | PRIMARY | 4 | NULL | 35 | Using where | +----+-------------+---------+-------+-----------------+---------+---------+------+------+-------------+Others encountered this problem before.
Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.