Hash Match in Query has high cost and high number of excecutions
If it used to run in 30 seconds, that means that something changed: you have to identify what that something is and fix it.

That something is most probably the query execution plan. There must be a better execution plan than the one that you're getting now, but the optimizer doesn't feel like giving you that plan any more. The reason can be only one: outdated statistics. 

Statistics become stale when you modify data in your tables and from time to time you need to update them. SQL Server will try to update statistics automatically when the number of changed rows exceeds a threshold that can be either static (20%) or adaptive (needs TF 2371 turned on). Either way, it's impossible to control the number of rows that SQL Server will scan to compile the statistics. This is particularly problematic when the distribution of the data is not uniform and you have skewed data. In that case, you'd better disable auto update statistics for the particular table/index and make sure that you update your statistics manually with FULLSCAN.

Another possible reason for getting an inefficient plan is parameter sniffing, but the reasoning behind is the same: your plan gets compiled for a non representative set of parameters, that determine  a performance nightmare when the plan is compiled for a more representative set of parameters. In this case, OPTIMIZE FOR hints might help, but usually fixing the stats is a better idea.

That said, if it used to run in 30 seconds you might still have the efficient plan lying around somewhere in the cache: try to find it in sys.dm_exec_cached_plans and compare it with the plan that you are getting now.