You will be better off _not_ 'normalizing' tags. CREATE TABLE Tags ( ArticleID int(11) unsigned NOT NULL, Tag varchar(255), INDEX(Tag), PRIMARY KEY(ArticleID,Tag) ) ENGINE=innoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci; LOAD DATA ... INTO Tags ...; Skip the rest of your steps. Now simplify the code elsewhere since you don't need to go through `TagMap` to get to a `tag`. And there is no need for `MEMORY`. (And possibly no advantage, anyway.) Nor a SHA1 kludge. Note that `INDEX(Tag)` will be "covering" when Joining from `Tag` to `ArticleID`. This is because InnoDB tacks the PK onto the end of each secondary index. (I did not follow your "missing tags" issue, but it might be simpler now that there is only one new table.) Example from Comments -- List articles have all of 3 specific tags: SELECT a.* FROM ( SELECT articleID FROM Tags WHERE tag IN ('foo', 'bar', thing') HAVING COUNT(*) = 3 ) AS t JOIN Articles AS a USING(articleID);