MySQL has a tendency to materialize subqueries -- not only is this overhead for reading and writing a temporary table but it can also affect the use of indexes in a more complicated query.
Here are three alternative solutions that do not require subqueries.
If ?
does not contain wildcards, then the simplest method is:
replace(replace(col2, '_', ' '), '-', ' ') in (?, ?, ?)
If it does, then change logic to use a single regular expression pattern:
replace(replace(col2, '_', ' '), '-', ' ') regexp ?
You can also explicitly adjust the pattern in the query:
replace(replace(col2, '_', ' '), '-', ' ') regexp
concat('(',
replace(replace(?, '_', '.'), '%', '.*'), ')|(',
replace(replace(?, '_', '.'), '%', '.*'), ')|(',
replace(replace(?, '_', '.'), '%', '.*'), ')'
)