这与我发布的另一个问题相似,但有人告诉我要拆分它们。
我有一个InnoDB MYSQL表,它存储一个多选名称(或表中调用的'code'),一个父对象的id(parent_id)以及在多选(name_id)中选择的选项的名称: / p>
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 ;
和一个存储名称的简单表(我想我会显示这个,因为它在查询中使用):
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 ;
我想针对以下查询进行优化:
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'
以上查询的EXPLAIN:
非常感谢你!我正在寻找关于从这些表中获得最佳性能的方法的建议。
答案 0 :(得分:1)
对于你的v2_CA_venues表,我看到你有一个索引ON(城市,状态)。在查询中使用此作为FIRST。您的地图表可以有1000个条目,但是单个“城市+状态”的数量是多少......更不用说了。现在,在查询的顶部将有助于优化其余部分。使用关键字“STRAIGHT_JOIN”会告诉优化器按照您说明的顺序执行此操作。
您拥有3way_unique
索引的索引,我会更改(或添加另一个索引),其中最小元素作为索引中的第一个位置...我实际上会将顺序更改为(parent_id,name_id ,代码)。你可以有100个代码,但是有1000个parent_ids。但是现在,你正在寻找一个可能有多个代码的特定父ID ...所以现在,你的索引将只有ex:ONE Parent_ID,它可能有8个代码,你正在寻找3.你已经只是减少了你加入的比较集。
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'