Domain functions do not belong in queries or in VBA loops. The proper method is to join the two tables.
Also with a 2+million row table, I would never join it to a linked flat file. Import the .csv to a table. Add indexes if appropriate. That will make the join as efficient as it can be.
A real world example --
A few years ago, I was employed to teach the analysts at a small startup company how to use Access to make their Excel work more efficient. Every day, they would come in and download yesterday's data from our transaction processing company. They would then import the data into their spreadsheets and start their VLookup()s running and head out for breakfast. 2-3 hours later, the files would be ready to be used for analysis.
I started with one simple change. Import the downloaded data into Access and join the files rather than doing VLookup()s or the Access equivalent which is dLookup(). Less than 5 minutes later, the data was exported to their Excel workbooks ready to go. That is the power of a join vs a domain function when you are dealing with MILLIONS of rows of data as they were and as you are. About 30% of my students "got" Access and were able to move a large part of their work to Access which made long running Excel jobs a thing of the past for them. The others didn't get it so they stuck with the old way but I still saved them a wasted 2 hours a day minimum by just getting rid of the VLookups.
A dLookup() and all the other domain functions as well, performs a query so when you use a dLookup() in a query, you are essentially running a separate query for every single row of your RecordSource. If it contained 1000 rows, you were running 1000 queries. If it was 2 million rows, you were running 2 million queries. Even if there were useful indexes, there is overhead associated with simply running a query and when you do it 2 million times, that adds up to one heck of a lot of overhead