我正在優化我的查詢並發現了一些我無法控制的問題。子查詢處理多於必要的行數
我使用下面的查詢選擇了一堆類的,他們用別名從包含新老別名類別表結合:
SELECT `c`.`id` AS `category.id`,
(SELECT `alias`
FROM `aliases`
WHERE category_id = c.id
AND `old` = 0
AND `lang_id` = 1
ORDER BY `id` DESC
LIMIT 1) AS `category.alias`
FROM (`categories` AS c)
WHERE `c`.`status` = 1 AND `c`.`parent_id` = '11';
只有2個類別,有值11對於parent_id
,所以它應該從別名表中查找2個類別。
不過,如果我用EXPLAIN
它說,它必須處理48行。別名表也包含每個類別1個條目(在這種情況下,它可以更多)。一切都被索引,如果我理解正確,因此它應該立即找到正確的別名。
現在,這裏是奇怪的事情。當我不根據條件中的類別比較別名時,但通過查詢返回的類別ID手動比較別名時,它只處理1行,與索引一樣。
所以我通過WHERE category_id IN (37, 43)
更換WHERE category_id = c.id
和查詢變快:
我能想到的唯一的事情就是子查詢沒有結束從查詢的結果運行,但之前的一些過濾已經完成了。歡迎任何形式的解釋或幫助!
編輯:傻我,WHERE IN
不起作用,因爲它不會作出獨特的選擇。問題仍然存在!
創建表模式
CREATE TABLE `aliases` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lang_id` int(2) unsigned NOT NULL DEFAULT '1',
`alias` varchar(255) DEFAULT NULL,
`product_id` int(10) unsigned DEFAULT NULL,
`category_id` int(10) unsigned DEFAULT NULL,
`brand_id` int(10) unsigned DEFAULT NULL,
`page_id` int(10) unsigned DEFAULT NULL,
`campaign_id` int(10) unsigned DEFAULT NULL,
`old` tinyint(1) unsigned DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product_id` (`product_id`),
KEY `category_id` (`category_id`),
KEY `page_id` (`page_id`),
KEY `alias_product_id` (`product_id`,`alias`),
KEY `alias_category_id` (`category_id`,`alias`),
KEY `alias_page_id` (`page_id`,`alias`),
KEY `alias_brand_id` (`brand_id`,`alias`),
KEY `alias_product_id_old` (`alias`,`product_id`,`old`),
KEY `alias_category_id_old` (`alias`,`category_id`,`old`),
KEY `alias_brand_id_old` (`alias`,`brand_id`,`old`),
KEY `alias_page_id_old` (`alias`,`page_id`,`old`),
KEY `lang_brand_old` (`lang_id`,`brand_id`,`old`),
KEY `id_category_id_lang_id_old` (`lang_id`,`old`,`id`,`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=112392 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
Eh?該模式與「SELECT」不匹配 - 「status」和「parent_id」在哪裏? –
'status'和'parent_id'來自主表('categories'),而不是子查詢(注意'c'別名) – Tumtum