开发者

Speed up this JOIN, MySQL

This is similar to another question I posted, but I was told to split them.

I have a InnoDB MYSQL table that stores a multi select name ( or 'code' as the table calls it), a parent object's id (parent_id) and the name of the option selected in the multi select (name_id):

CREATE TABLE IF NOT EXISTS `v2_CA_venue_option_map` (
  `map_id` int(11) NOT NULL auto_increment,
  `code` varchar(30) NOT NULL,
  `parent_id` int(11) NOT NULL,
  `name_id` int(11) NOT NULL,
  PRIMARY KEY  (`map_id`),
  UNIQUE KEY `3way_unique` (`code`,`parent_id`,`name_id`),
  KEY `name_id` (`name_id`),
  KEY `filter` (`code`,`name_id`),
  KEY `parent_id` (`parent_id`),
  KEY `code` (`code`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=875156 ;

and a simple table to store the names (i figured i would show this because its used in the query):

CREATE TABLE IF NOT EXISTS `v2_CA_venue_option_name` (
  `name_id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY  (`name_id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COMMENT='Venue Option Names' AUTO_INCREMENT=60 ;

CREATE TABLE IF NOT EXISTS `v2_CA_venues` (
  `venue_id` int(11) NOT NULL auto_increment,
  `status` char(1) NOT NULL,
  `name` varchar(255) NOT NULL,
  `url_key` varchar(255) NOT NULL,
  `city` varchar(255) NOT NULL,
  PRIMARY KEY  (`venue_id`),
  KEY `city` (`city`,`status`),
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ;

That I would like to optimize for the following query:

SELECT v.name, v.venue_id, v.url_key
FROM `v2_CA_venue_option_map` map
JOIN `v2_CA_venue_option_map` map2 ON (map2.parent_id = map.parent_id)
JOIN `v2_CA_venue_option_map` map3 ON (map3.parent_id = map.parent_id)
JOIN `v2_CA_venues` v ON (v.venue_id = map.parent_id)
WHERE v.city = 'Nevada City'
AND map3.code = 'a_venue_types'
AND map3.name_id = 19
AND map.code = 'a_event_types'
AND map.name_id = 20
AND map2.code = 'a_event_types'
AND map2.name_id = 3
AND v.status = 'a'
  1. Are the indexes placed on the table offering the best performance for these Joins and WHEREs?
  2. Are any of the indexes useless?

The EXPLAIN for the 开发者_如何学Goabove query:

Speed up this JOIN, MySQL

Thank you so much! I am looking for advice on the way to get the best performace out of these tables.


FOR your v2_CA_venues table, I see you have an index ON( City, Status ). Use this as the FIRST IN your query. Your maps table could have 1000's of entries, but how many for a single "City + Status"... much less. So now that at the top of your query will help optimize the rest. Using the keyword "STRAIGHT_JOIN" tells optimizer to do it in the order you've stated.

What you have of an index of 3way_unique index, I would change (or add another index) with the smallest element as first position in the index... I would actually change the order to ( parent_id, name_id, code ). You could have 100 codes, but 1000's of parent_ids. But now, you are looking for a specific parent ID that could have multiple codes... So now, your index would be down to just ex: the ONE Parent_ID and it may have 8 codes and you are looking for 3. You've just reduced your comparison set for the join.

SELECT STRAIGHT_JOIN
      v.name, 
      v.venue_id, 
      v.url_key
   FROM 
      v2_CA_venues v

         join v2_CA_venue_option_map map 
            ON v.venue_id = map.parent_id
            AND map.name_id = 20
            and map.code = 'a_event_types'

         join v2_CA_venue_option_map map2
            ON v.venue_id = map2.parent_id
            AND map2.name_id = 3
            and map2.code = 'a_event_types'

         join v2_CA_venue_option_map map3
            ON v.venue_id = map3.parent_id
            AND map3.name_id = 19
            and map3.code = 'a_venue_types'

   where 
          v.City = 'Nevada City'
      and v.status = 'a'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜