1 hour query, is there another way to do this?
No way!  Every 'end' is not optimizable because of the leading wildcard.  That means that if there are, say, a mere 3K 'end' entries in match, then there will be over a billion (350K * 3K) tests to perform!

The query can be partially optimized by

INDEX(type, string) -- in `match`
INDEX(name) -- in `user`
SELECT ... FROM user JOIN match ON match.type='exact' AND user.name=match.string
UNION ALL
SELECT ... FROM user JOIN match ON match.type='begin' AND user.name LIKE CONCAT...
UNION ALL
SELECT ... FROM user JOIN match ON match.type='end' AND user.name LIKE CONCAT...;



The match INDEX minimizes the effort in finding the relevant rows.
The user INDEX is useful for the first two SELECTs.
The UNION lets the optimizer operate on each SELECT independently.
The ALL avoid a de-dupping phase that is (I assume) unnecessary.


Have you considered a FULLTEXT index?  If it works, it will be a million times as fast.  (Perhaps literally a million!)

Here's a kludge that can make the third SELECT sargable (gee, I learned a new word!) -- Reverse both the match.string and the user.name, then do the LIKE like 'begin'.  No, don't use the REVERSE function in this query, actually build the two tables (or maybe a separate pair of tables) with the reversed strings.