mysql - Subquery processing more rows than necessary -
i optimising queries , found can't head around.
i using following query select bunch of categories, combining them alias table containing old , new aliases categories:
select `c`.`id` `category.id`, (select `alias` `aliases` category_id = c.id , `old` = 0 , `lang_id` = 1 order `id` desc limit 1) `category.alias` (`categories` c) `c`.`status` = 1 , `c`.`parent_id` = '11'; there 2 categories value of 11 parent_id, should 2 categories alias table.
still if use explain says has process 48 rows. alias table contains 1 entry per category (in case, can more). indexed , if understand correctly therefore should find correct alias immediately.
now here's weird thing. when don't compare aliases categories conditions, manually category ids query returns, process 1 row, intended index.
so replace where category_id = c.id where category_id in (37, 43) , query gets faster:
the thing can think of subquery isn't run on results query before filtering done. kind of explanation or welcome!
edit: silly me, where in doesn't work doesn't make unique selection. question still stands though!
create table schema
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;
select ... x=1 , y=2 order id desc limit 1 will performed in 1 of several ways.
since have not shown indexes have (show create table), cover cases...
index(x, y, id)-- can find last row condition, not need @ more 1 row.- some other index, or no index: scan descending last
idchecking each rowx=1 , y=2, stopping when (if) such row found. - some other index, or no index: scan entire table, checking each row
x=1 , y=2; collect them temp table; sortid; deliver 1 row.
some of explain clues:
- using -- not much
- using filesort -- did sort, apparently
order by. (it may have been entirely done in ram; ignore 'file'.) - using index condition (not "using index") -- indicates internal optimization in can check
whereclause more efficiently used in older versions.
do not trust "rows" in explain. reasonably correct, off orders of magnitude. here better way see "how work" being done in rather fast query:
flush status; select ...; show session status 'handler%'; with create table, may have suggestions on how improve index.



Comments
Post a Comment