I have a data warehouse database and I'm facing problems with the new cardinality estimator of SQL Server 2014.
After upgrading the database server to SQL Server 2014 I have observed a big difference in query performance. Some queries are executing much slower (30 sec in SQL 2012 vs. 5 minutes in SQL 2014). After researching execution plans I've seen that the cardinality estimates on the SQL Server 2014 are way off and I can't find a reason for it.
Here's an example of a query execution plan (top-left operator) in SQL 2012 vs. SQL 2014:
Some details:
My queries are typical data warehouse fact table load queries. I query a transactional table and join a lot (15-20) dimension tables (there's always either 0 or 1 record that is joined from the dimensional table).
I have updated statistics of all tables (with FULLSCAN) to be sure that the statistics is up-to-date.
The business keys of the dimension tables are indexed (unique non-clusted index). It seems to me that because of the uniqueness of this index the old cardinality estimator (SQL 2012) correctly assumes that there's max. 1 record that joins (the estimated number of records does not change in the execution plan).
I tried to narrow down the issue to the simplest example – SELECT with 2 joins:
Here's the cardinality estimation on operators 1 and 2 in SQL 2012 vs. SQL 2014:
| Est.rows - SQL2012 | Est.rows - SQL2014
Operator 1 | 7653 | 7653
Operator 2 | 7653 | 10000
As you can see, SQL Server 2014 misses the estimation by more than 30% (10000 vs. 7653). Because I have cca. 15-20 joins in a typical query, the final estimate goes way off.
I can put the database in the lower compatibility mode (110) and it works fine then (same like on SQL Server 2012), but I would really like to know what is the reason for this behaviour. Why is the result of cardinality estimator of SQL Server 2014 wrong?
In 1998, a major update of the CE was part of SQL Server 7.0, for which the compatibility level was 70.
This allows users with lower permissions to change the Cardinality Estimator for execution of the problematic statement.
Cardinality estimation (CardEst) plays a significant role in generating high-quality query plans for a query optimizer in DBMS. In the last decade, an increasing number of advanced CardEst methods (especially ML-based) have been proposed with outstanding estimation accuracy and inference latency.
What is a Cardinality Estimate? A cardinality estimate is the estimated number of rows, the optimizer believes will be returned by a specific operation in the execution plan.
I think there is no simple answer today to this interesting question. The best answer I know is the following video: http://channel9.msdn.com/events/TechEd/NorthAmerica/2014/DBI-B331#fbid=. It has numerous examples of new and old estimators. The video is about 50+ mins long but it is worth the time.
A summary of the video that relates to this question:
Old assumptions of cardinality estimates:
To Use SQL SERVER 2012 cardinality estimator in SQL SERVER 2014 use the following option:
What is new estimator doing (based on video):
To do / checklist:
1. Auto Create / Update Stats
2. Check database compatibility mode (120/110)
3. Test using query trace flags
4. XML showplan
Update What's new in cardinality estimator (SQL Server 2016)
More details:
https://docs.microsoft.com/en-us/sql/relational-databases/performance/cardinality-estimation-sql-server
https://www.sqlshack.com/query-optimizer-changes-in-sql-server-2016-explained/
I wonder if you are running into this issue around multicolumn selectivity estimates:
http://www.sqlskills.com/blogs/kimberly/multi-column-statistics-exponential-backoff/
it seems that there are still some quirks with the new CE try also using TF 4137 as outlined and see if that helps.
finally make sure you are on the latest CU and are running with TF 4199 to blanket enable all query optimizer fixes as always test this in a non-production environment if possible first and be mindful of regressions in other queries when enable settings globally
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With