3

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 ;

That I would like to optimize for the following query:

SELECT DISTINCT name_id, name 
FROM `v2_CA_venue_option_map` 
JOIN `v2_CA_venue_option_name` 
    USING (name_id) 
WHERE code = "a_event_types"

This query takes about 600ms to execute and I was wondering:

  1. If I could place an index on the table to speed up this distinct query.
  2. How could I get the same result with better performance.

Here is an explain of the above query.

enter image description here

UPDATE, I removed my second question.

UPDATE, It seems that the best way to speed this up would be to store the output in a separate table once and make the calls to that table from then on, as this table just can't perform the query quick enough for my needs and indexes don't seem to help for this DISTINCT query.

RonSper
  • 693
  • 1
  • 7
  • 19
  • 1
    If you have multiple questions, you should create multiple topics for them, as people will be more likely to help. – Igor Sep 27 '11 at 20:58
  • 1
    You also might want to paste an explain plan for your query. It would help to see what MySQL's optimizer is doing. – Kris Robison Sep 27 '11 at 21:05
  • How long it takes to run this query and how many rows it returns? `select name_id from v2_CA_venue_option_map where code = "a_event_types" group by name_id` – Karolis Sep 27 '11 at 21:49
  • 1
    Your query: ( 19 total, Query took 0.4048 sec) – RonSper Sep 27 '11 at 22:02
  • 1
    @RonSper Oh.. so it seems that you are right, your query can't perform much better. – Karolis Sep 27 '11 at 22:24

2 Answers2

0

Try a lazy group by instead of distinct, it's one less column mysql has to worry about.

SELECT name_id, name 
FROM `v2_CA_venue_option_map` 
JOIN `v2_CA_venue_option_name` 
    USING (name_id) 
WHERE code = "a_event_types"
GROUP BY name_id
Parris Varney
  • 11,320
  • 12
  • 47
  • 76
0

You can try changing the query from a join to a semi-join, using EXISTS. No need for DISTINCT:

SELECT name_id
     , name 
FROM v2_CA_venue_option_name AS n
WHERE EXISTS
      ( SELECT *
        FROM v2_CA_venue_option_map AS m
        WHERE m.name_id = n.name_id 
          AND m.code = 'a_event_types'
      )
ypercubeᵀᴹ
  • 113,259
  • 19
  • 174
  • 235
  • 1
    thanks for the suggestion. 19 total, Query took 5.6770 sec, not even close to the performance of DISTINCT. – RonSper Sep 27 '11 at 23:03