We decided to migrate a MS SQL Server 2014 a DB into a different server that runs 2016. Now the PHP application that uses this DB has slowed down its performance significantly (queries have jumped from 1 or 2 seconds to 20), although the DB is identical in terms of schema, structure and data. The new server has higher CPU, disk and memory params and the workload is just normal, so this decrease in performance had no sense in the beginning.
Then I analyzed some queries with the Profiler and I was surprised to see that the query plan is different when it runs in either Management Studio (fast, 1 to 3 seconds) or the application front-end (slow, 15 to 25 seconds).
I found this link, and this other too, but after reading a lot and trying different things I can't fix the issue. Has anyone dealt with this before? Any hints about quick things to check before diving deeply?
Thanks!
============
EDIT 1
The query returns just few records, depending on the values of the filters, but something 10 and 1000 (never more than that because it is topped 1000). The main table being queried contains 1 million of records, not much, and whole DB weights around 4 GB. Indexes were migrated successfully, then rebuild and statistics updated.
EDIT 2
AMong the things I tried is rebuild all DB indexes and update all DB tables statistics. I forced RECOMPILE several times too (from Management Studio only). I used index hints to force some indexes to be used (from Management Studio only). None of these helped me fix the issue. Regarding the query plans, they are very very difficult to analyze because my queries are joining about 20 tables and have several subqueries.
EDIT 3
Just to clarify, the query that produces different execution plans is identical even with the parameters. I mean, I run the query from the front-end while a profiler trace is active, the query is captured (takes around 20 seconds) and I copy the text and paste it in management studio, run the same query and get the results in just 2 seconds, plus a different execution plan. Could this kind of issue still be related with parameter sniffing?