Server A and Server B have identical hardware and instance configurations (A is Production, B is QA). B's DBs were restored from A's backups from one week ago. I was provided this query by the development team.
SELECT
c.Start
,c.[End]
,c.Word
,doc.UniqueDocumentNumber
,doc.EID
,c.CUI
,c.Concept
,a.OID
,doc.DocumentTypeName
,doc.ActivityDtTm
,CAST(doc.DocumentTypeId AS INT) AS MedCode
,CASE WHEN c.[Count] = 0 THEN CAST(0.00 AS REAL)
ELSE CAST(LOG(c.TotalCount / c.[Count]) AS REAL) END AS 'idf'
,c.[Count]
,c.TotalCount
FROM ECHO..AEID201 a
INNER JOIN ALPHA..XADocuments doc (NOLOCK) ON a.EID = doc.EID
CROSS APPLY (SELECT t.start,t.[end],t.word,t.cui,t.eid,
t.UniqueDocumentNumber,cu.[Count],cc.TotalCount,core.Concept
FROM HOTEL.dbo.Htf_Index AS t
INNER JOIN HOTEL..Doc_CUI_Counter AS cu ON cu.CUI=t.CUI AND cu.DocumentTypeID=t.DocumentTypeID
INNER JOIN HOTEL..Doc_Counter AS cc ON cc.DocumentTypeID=t.DocumentTypeID
INNER JOIN HOTEL..CUI_CORE AS core ON core.CUI=cu.CUI
WHERE t.eid = doc.eid AND doc.UniqueDocumentNumber=t.UniqueDocumentNumber
) AS c
WHERE a.OID='00005159-9567-4187-a278-5b8e1e2ed20c'
AND ISNUMERIC(doc.DocumentTypeId) = 1
On Server B, review of the execution plan indicates that the criteria for table [a] at bottom is part of an index seek operation at the start of the execution plan, which makes the subquery [c] resultset execute rapidly.
On Server A, review of the same execution plan indicates that subquery [c] is executing first with full index scans due to outer criteria not being applied.
Indexes utilized in both execution plans are identical. Table rows counts are slightly larger on Server A since the restore due to normal operations but index fragmentation is nearly identical. A participating index on table [t] in the subquery on Server B has double the number of pages as on Server A but identical row count. Statistics are updated nightly at the same time on both servers.
I've attempted index rebuilds on table [t] and manually updating statistics to attempt to get both execution plans to match. What other factors may be causing this change in the order of execution?
I suggested to the developer replacing the subquery with a UDF that takes the EID and UniqueDocumentNumber fields from [doc] as arguments. What other options can I explore with the developer to increase the probability of the execution plans on QA being utilized on Prod?