2015-02-04 51 views
0

我爲了來加速搜索功能的產品,價格升序排序添加一個索引(IDX_D34A04AD46C53D4C41FA5CD2)我product表:MySQL使用WHERE + ORDER BY(索引的兩個部分)解釋不使用索引?

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; 

搜索活躍的產品,按價格排序,顯示50項每頁:

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

輸出:

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

你能簡單解釋一下我做錯了和W我不能在我的例子中實現「使用索引條件」?

EDIT:從MySQL文檔:

下列查詢使用該索引來解決ORDER BY部分:

SELECT * FROM T1 WHERE key_part1 =常數ORDER BY key_part2;

這看起來和我的例子完全一樣。

+0

表中有多少行? –

+0

@EricPetroelje現在〜9000 – gremo

回答

1

這是您的查詢:

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

因爲你有is_enabled的不平等狀況,它結束了索引的使用。因此,索引不能用於unit_price。或者,也可以將其用於unit_price和排序,但篩選將在輸出中完成。

下應該使用索引:在「額外」列

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

不幸的是,EXPLAIN的輸出非常相似。 – gremo

+0

有什麼我可以做的,以瞭解什麼是錯的?當我投入生產時,產品將約爲20000,我害怕表演。 – gremo

+1

@gremo,Gordon在第二個查詢中顯示瞭解決方案:在您的WHERE而不是'> 0'中使用'= 1'比較。如果您在'is_enabled'中搜索一個特定值,那麼匹配的行可以按'unit_price'排序。按這個順序在這兩列上創建一個索引。 –

1

值「利用指數」表明,MySQL將使用覆蓋索引,以避免訪問表。不是這種情況。

您的查詢使用索引(is_enabled,unit_price),但它不使用覆蓋索引,因爲您正在檢索SELECT語句中的所有列。