Sanket Gupta
Sanket Gupta

Reputation: 573

Mysql Index issue

Can somebody tell me why mysql is not using the correct index in the following query

SELECT `Slugs`.`slug` FROM `slugs` AS `Slugs`   
WHERE `Slugs`.`country_id` = 1 AND `Slugs`.`expired` = 0    
LIMIT 308400,300

I have created a cmposite index for the two columns refered in the where clause

Table Structure for table slugs

CREATE TABLE IF NOT EXISTS `slugs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `slug` varchar(255) NOT NULL,
  `post_fields` text NOT NULL,
  `slugdata` text NOT NULL,
  `updated_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `country_id` int(11) NOT NULL DEFAULT '1',
  `expired` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `slug_2` (`slug`,`country_id`),
  KEY `updated_date` (`updated_date`),
  KEY `country_id` (`country_id`),
  KEY `slug` (`slug`),
  KEY `expired` (`expired`),
  KEY `country_id_2` (`country_id`,`expired`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1612485 ;

Indexes:

Keyname      Type   Unique  Packed  Field        Cardinality     Collation  Null    Comment
PRIMARY      BTREE  Yes     No      id               1406994      A     
slug_2       BTREE  Yes     No      slug             1406994      A     
                                    country_id       1406994      A 
updated_date BTREE  No      No      updated_date          21      A     
country_id   BTREE  No      No      country_id            21      A     
slug         BTREE  No      No      slug             1406994      A     
expired      BTREE  No      No      expired               21      A     
country_id_2 BTREE  No      No      country_id            21      A     
                                    expired               21      A

Output from Explain

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  Slugs   ref     country_id,expired,country_id_2     country_id  4   const   670284  Using where

Upvotes: 0

Views: 401

Answers (1)

symcbean
symcbean

Reputation: 48357

What do you mean it's not using the correct index?

The cardinality for both country_id and country_id_2 is very low, and is in fact the same for both indexes - so there's no benefit in using the index based on 2 columns. Which implies that there are very few records with expired<>0.

But then why does the expired index have a cardinality of 21 too?

What's the output from:

SELECT 'expired' AS fld
, COUNT(*) AS distinct_values
, AVG(n) AS rows
FROM 
(SELECT expired AS v
 , COUNT(*) AS n 
 FROM slugs 
 GROUP BY expired) ilv1
UNION
SELECT 'country_id',
, COUNT(*) AS distinct_values
, AVG(n) AS rows
FROM 
(SELECT country_id AS v
 , COUNT(*) AS n 
 FROM slugs 
 GROUP BY country_id) ilv2
    SELECT 'expired:country_id',
, COUNT(*) AS distinct_values
, AVG(n) AS rows
FROM 
(SELECT CONCAT(expired, country_id) AS v
 , COUNT(*) AS n 
 FROM slugs 
 GROUP BY CONCAT(expired, country_id)) ilv3;

Upvotes: 1

Related Questions