Bug #28612 Optimizer does not use index for BETWEEN in a JOIN condition

Submitted: 23 May 2007 7:30 Modified: 24 Jun 2007 13:27
Reporter: Ondra Zizka Email Updates:
Status: No Feedback Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S5 (Performance)
Version:5.0.37 OS:Any
Assigned to: CPU Architecture:Any
Tags: between, INDEX, Indices, keys, left join, Optimizer

[23 May 2007 7:30] Ondra Zizka
Description:
When using BETWEEN in a LEFT JOIN condition, the index is not used for the column subjecting to BETWEEN. When used with >= AND <=, index is used.

How to repeat:
DROP TABLE IF EXISTS `stats_download`;
CREATE TABLE  `stats_download` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `lrc_id` int(10) unsigned NOT NULL default '0',
  `tm` int(10) unsigned NOT NULL default '0',
  `ip` int(10) unsigned NOT NULL default '0',
  `country_code` smallint(6) unsigned NOT NULL default '0',
  `reg_num` int(10) unsigned NOT NULL default '0',
  `progver` smallint(5) unsigned NOT NULL default '0',
  `err` tinyint(3) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `prog_ver` (`progver`),
  KEY `err` (`err`),
  KEY `lrc_id` (`lrc_id`),
  KEY `tm` (`tm`),
  KEY `ip` (`ip`),
  KEY `country_code` (`country_code`),
  KEY `reg_num` (`reg_num`)
) ENGINE=MyISAM;

CREATE TABLE stats_download_locations (
  id INT UNSIGNED NOT NULL PRIMARY KEY,
  id_location INT UNSIGNED, INDEX (id_location)
);

DROP TABLE IF EXISTS `gi_blocks`;
CREATE TABLE  `gi_blocks` (
  `start_ip` int(10) unsigned NOT NULL default '0',
  `end_ip` int(10) unsigned NOT NULL default '0',
  `id_location` int(10) unsigned NOT NULL default '0',
  KEY `si` (`start_ip`),
  KEY `ei` (`end_ip`)
) ENGINE=MyISAM COMMENT='IP ranges';

EXPLAIN
SELECT sd.id, gb.id_location FROM stats_download AS sd
LEFT JOIN geoip.gi_blocks AS gb ON sd.ip >= gb.start_ip AND sd.ip <= gb.end_ip
WHERE sd.id BETWEEN 29000000 AND 29001000;

EXPLAIN
SELECT sd.id, gb.id_location FROM stats_download AS sd
LEFT JOIN geoip.gi_blocks AS gb ON sd.ip BETWEEN gb.start_ip AND gb.end_ip
WHERE sd.id BETWEEN 29000000 AND 29001000;

While the first SELECT has 'si,ei' AS possible_keys for the table 'gb',
the second has NULL.

Suggested fix:
Let BETWEEN use the indices like >= and <= would use.
[24 May 2007 13:27] Valeriy Kravchuk
Thank you for a problem report. Please, try to repeat with a newer version, 5.0.41, and, in case of the same problem, send also some data/INSERT statements that demonstrates the prbolem described.
[24 Jun 2007 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.054 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
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.