Can anyone tell me why this makes sense?  I have a SELECT which uses an indexed 
datetime field called Start with a BETWEEN range.  If I select on this with no 
LIMIT, it does a full scan of the 9391282 records in the DB (key=NULL).  
However, if I do a limit of any value LESS than the number of records in the 
DB, it uses the index (key=Start).  If I do a LIMIT of any value greater than 
the number of records in the DB it again doesn't use the index (key=NULL).

This is on MySQL 4.0.18.  Am I missing a bug fix in a more recent version of 
MySQL?


mysql> SHOW CREATE TABLE BillingLog;

| BillingLog |CREATE TABLE `BillingLog` (
  `CallID` bigint(20) unsigned NOT NULL default '0',
  `ChargeType` char(5) NOT NULL default '',
  `DNIS` char(10) NOT NULL default '',
  `Application` char(15) NOT NULL default '',
  `Duration` int(11) NOT NULL default '0',
  `VoiceSystem` char(8) NOT NULL default '',
  `Mailbox` char(15) NOT NULL default '',
  `PhoneNumber` char(20) NOT NULL default '',
  `InfoDigs` char(2) NOT NULL default '',
  `BillingRate` char(5) NOT NULL default '',
  `TimeStamp` timestamp(14) NOT NULL,
  `Sequence` bigint(20) NOT NULL auto_increment,
  `Start` datetime NOT NULL default '0000-00-00 00:00:00',
  `End` datetime NOT NULL default '0000-00-00 00:00:00',
  `Provider` char(5) NOT NULL default '',
  `ProviderCost` double(15,3) NOT NULL default '0.000',
  `BillProvider` char(5) NOT NULL default '',
  `CustomerPrice` double(15,3) NOT NULL default '0.000',
  PRIMARY KEY  (`Sequence`),
  UNIQUE KEY `Sequence` (`Sequence`),
  KEY `Start` (`Start`),
  KEY `Application` (`Application`,`Start`),
  KEY `CallID` (`CallID`)
) TYPE=MyISAM |


mysql> EXPLAIN SELECT DATE_FORMAT(Start, '%m/%d/%Y %H:%i:%S'),  Duration,  
PhoneNumber,  DNIS,  Provider,  Sequence,  ProviderCost,  CustomerPrice,  
CallID  FROM  BillingLog  WHERE Start BETWEEN '20041001000000' AND 
'20041031000000';
+------------+------+---------------+------+---------+------+---------+-------------+
| table      | type | possible_keys | key  | key_len | ref  | rows    | Extra   
    |
+------------+------+---------------+------+---------+------+---------+-------------+
| BillingLog | ALL  | Start         | NULL |    NULL | NULL | 9391282 | Using 
where |
+------------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT 
    ->         DATE_FORMAT(Start, '%m/%d/%Y %H:%i:%S'), 
    ->         Duration, 
    ->         PhoneNumber, 
    ->         DNIS, 
    ->         Provider, 
    ->         Sequence, 
    ->         ProviderCost, 
    ->         CustomerPrice, 
    ->         CallID 
    ->   FROM 
    ->       BillingLog 
    ->   WHERE 
    ->       Start BETWEEN '20041001000000' AND '20041031000000'
    -> ;
+------------+------+---------------+------+---------+------+---------+-------------+
| table      | type | possible_keys | key  | key_len | ref  | rows    | Extra   
    |
+------------+------+---------------+------+---------+------+---------+-------------+
| BillingLog | ALL  | Start         | NULL |    NULL | NULL | 9391289 | Using 
where |
+------------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT 
    ->         DATE_FORMAT(Start, '%m/%d/%Y %H:%i:%S'), 
    ->         Duration, 
    ->         PhoneNumber, 
    ->         DNIS, 
    ->         Provider, 
    ->         Sequence, 
    ->         ProviderCost, 
    ->         CustomerPrice, 
    ->         CallID 
    ->   FROM 
    ->       BillingLog 
    ->   WHERE 
    ->       Start BETWEEN '20041001000000' AND '20041031000000'
    -> LIMIT 1000
    -> ;
+------------+-------+---------------+-------+---------+------+---------+-------------+
| table      | type  | possible_keys | key   | key_len | ref  | rows    | Extra 
      |
+------------+-------+---------------+-------+---------+------+---------+-------------+
| BillingLog | range | Start         | Start |       8 | NULL | 2061426 | Using 
where |
+------------+-------+---------------+-------+---------+------+---------+-------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT 
    ->         DATE_FORMAT(Start, '%m/%d/%Y %H:%i:%S'), 
    ->         Duration, 
    ->         PhoneNumber, 
    ->         DNIS, 
    ->         Provider, 
    ->         Sequence, 
    ->         ProviderCost, 
    ->         CustomerPrice, 
    ->         CallID 
    ->   FROM 
    ->       BillingLog 
    ->   WHERE 
    ->       Start BETWEEN '20041001000000' AND '20041031000000'
    -> LIMIT 10000000
    -> ;
+------------+------+---------------+------+---------+------+---------+-------------+
| table      | type | possible_keys | key  | key_len | ref  | rows    | Extra   
    |
+------------+------+---------------+------+---------+------+---------+-------------+
| BillingLog | ALL  | Start         | NULL |    NULL | NULL | 9391313 | Using 
where |
+------------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.01 sec)

mysql> EXPLAIN SELECT 
    ->         DATE_FORMAT(Start, '%m/%d/%Y %H:%i:%S'), 
    ->         Duration, 
    ->         PhoneNumber, 
    ->         DNIS, 
    ->         Provider, 
    ->         Sequence, 
    ->         ProviderCost, 
    ->         CustomerPrice, 
    ->         CallID 
    ->   FROM 
    ->       BillingLog 
    ->   WHERE 
    ->       Start BETWEEN '20041001000000' AND '20041031000000'
    -> LIMIT 2000000
    -> ;
+------------+-------+---------------+-------+---------+------+---------+-------------+
| table      | type  | possible_keys | key   | key_len | ref  | rows    | Extra 
      |
+------------+-------+---------------+-------+---------+------+---------+-------------+
| BillingLog | range | Start         | Start |       8 | NULL | 2061431 | Using 
where |
+------------+-------+---------------+-------+---------+------+---------+-------------+
1 row in set (0.05 sec)


Jeremiah Gowdy
Senior Software Engineer
FreedomVOICE Systems

Reply via email to