我的表格设置如下(为了简洁起见,从movies
删除了一些列):
CREATE TABLE `movies` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '',
`alias` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `alias` (`alias`),
KEY `title` (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `movies_x_genre` (
`movieid` int(11) NOT NULL,
`genreid` int(11) unsigned NOT NULL,
PRIMARY KEY (`movieid`,`genreid`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `genre` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`genre` varchar(100) NOT NULL,
`group` int(11) unsigned DEFAULT NULL,
`type_id` tinyint(1) DEFAULT NULL,
`valid` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `genre` (`genre`,`type_id`),
KEY `idx_genre` (`genre`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我有有效或无效的流派
INSERT INTO `genre` (`id`,`genre`,`group`,`type_id`,`valid`) VALUES
(1,"Comedy",1,1,1),
(2,"Comedies",1,1,0),
(3,"Action",2,1,1),
(4,"Acton",2,1,0);
INSERT INTO `movie_x_genre` (`movieid`,`genreid`) VALUES
(1,1),
(2,2),
(1,3),
(2,4);
我面临的问题是,我将电影类型以多种语言存储到流派表中,并且通常是某些语言中流派的变体,
每个具有相同含义,或至少相同含义但使用不同语言的类型都有一个共同的“组”ID存储在手动设置的group
列中,
电影与它附带的类型相结合,并且类型以新的id存储在数据库中,如果它是一个新的类型,这允许我现在存储该类型并使其可用并在以后修复它,如果它应该属于一个群体,因为我根本无法每天手动分组。
类型的语言ID存储在type_id中,而valid
列标记了类型名称的哪个变体是正确的。
当我运行以下查询时,无论使用何种语言或变体,选择“喜剧”类型的所有电影
当我选择“Comedies”时,我想选择id为1且id为2的电影,因为它们都是comiedies,只是用不同的方式写的 但是选择查询非常慢,大约需要0.5秒 当我运行下面的部分时,我看到“复制到tmp表”需要很长时间
SET profiling = 1;
SELECT SQL_NO_CACHE i.id,i.alias,i.title
FROM genre g
INNER JOIN genre g2 ON g.`group`=g2.`group`
INNER JOIN movies_x_genre x ON x.genreid=g.id
INNER JOIN movies i ON i.id=x.movieid
WHERE g2.`genre` = "comedy"
GROUP BY i.id;
SHOW profile;
我遇到了这个答案skip copying to tmp table on disk mysql然后跑了
SHOW VARIABLES LIKE '%tmp_table_size%';#1073741824 = 1GB
SHOW VARIABLES LIKE '%max_heap_table_size%';#1073741824 = 1GB
我认为我不应该增加这些
为什么选择这么慢?我是否正确组织了桌子?我错过了索引吗?如果他们错了,我该如何组织我的桌子?存储信息以过滤电影的最有效方法是什么?