简体   繁体   中英

MySQL EXPLAIN not using index with WHERE + ORDER BY (both part of the index)?

I've added an index ( IDX_D34A04AD46C53D4C41FA5CD2 ) to my product table in order to speed-up searching for enabled products, ordered by price ascending:

CREATE TABLE `product` (
  `id` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
  `unit_price` decimal(13,4) NOT NULL,
  `stock_qty` int(11) DEFAULT NULL,
  `is_enabled` tinyint(1) NOT NULL,
  `min_sale_qty` int(11) DEFAULT NULL,
  `max_sale_qty` int(11) DEFAULT NULL,
  `package_qty` int(11) DEFAULT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `is_new` tinyint(1) NOT NULL,
  `created_at` date NOT NULL,
  `package_type` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_D34A04ADBF396750` (`id`),
  KEY `IDX_D34A04AD41FA5CD2` (`unit_price`),
  KEY `IDX_D34A04AD46C53D4C` (`is_enabled`),
  KEY `IDX_D34A04AD46C53D4C41FA5CD2` (`is_enabled`,`unit_price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Searching for active products, order by price, showing 50 items per page:

EXPLAIN SELECT * FROM product WHERE is_enabled > 0 ORDER BY unit_price ASC LIMIT 0, 50;

Output:

1   SIMPLE  product index   IDX_D34A04AD46C53D4C,IDX_D34A04AD46C53D4C41FA5CD2   IDX_D34A04AD41FA5CD2    6       100 Using where

Can you simple explain what I'm doing wrong and why I can't achieve "Using Index Condition" in my example?

EDIT : from MySQL documentation:

The following queries use the index to resolve the ORDER BY part:

SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2;

It seems exactly the same example as mine.

This is your query:

SELECT *
FROM product
WHERE is_enabled > 0
ORDER BY unit_price ASC
LIMIT 0, 50;

Because you have an inequality condition on is_enabled , it ends the index usage. So, the index cannot be used for unit_price . Or, alternatively, it could be used for unit_price and the sorting, but the filtering would be done on output.

The following should use the index:

SELECT *
FROM product
WHERE is_enabled = 1
ORDER BY unit_price ASC
LIMIT 0, 50;

The value “Using index” in the "Extra" column indicates that MySQL will use a covering index to avoid accessing the table. This is not the case.

Your query is using the index (is_enabled,unit_price), but it's not using a covering index because you are retrieving all the columns in the SELECT statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM