There are entire courses dedicated to the topics of MSSQL query optimization.
I’d start with sp_whoisactive while the query is running http://whoisactive.com/ and see if your query is blocking or being blocked by other queries. You’ll see reads and cpu metrics. You can also see blocker information in Activity monitor.
SET STATISTICS TIME,IO ON
To the top of your statement so you get information on runtime, logical reads + writes and such after the query finishes. (Assuming it ever does)
Turn on Query Store in your database, and use it to analyze the execution plans while they run and/or for past queries within the database.
Use sp_Blitz https://www.brentozar.com/blitz/ to analyze your cached execution plans, indexes (or missing indexes), and use BlitzFirst to see how your overall server configuration is w.r.t. best practices. Speaking of best practices, ensure your server follows this: https://www.brentozar.com/archive/2014/06/sql-server-setup-checklist-free-ebook-download/
Maybe leverage this:
To see your locking/wait stats over time and look for bottlenecks. Or use a more automated tool for alerting - Red Gate SQL Monitor is great for doing realtime alerts on long running queries or blocking queries, (with a realtime tree view). SolarWinds DPA (Database Performance Analyzer) is great for tracking wait stats, point-in-time query information, execution plans and blockers and wait stats on a regular basis.
Look at the actual execution plan in SSMS… perhaps using TOP 100, TOP 1000, TOP 10000 etc to make it run faster and hopefully glean some information on where the greatest cost is.
SQL Sentry Plan Explorer is another great tool to look at execution plans and do analysis of total waits/reads/writes/cpu in a tree view as well as pictorially.