Hi,
I am working on a query optimization task . My actual query is mentioned below which is taking 16 seconds to load for a period of 1 month. The problem I am facing over here is when exclude the part highlighted in bold below my query is running fine.
But when I include the part highlighted in bold I am getting an error as :
Error: «Msg 8624, Level 16, State 17, Line 82
Internal Query Processor Error: The query processor could not produce a query plan. For more information, contact Customer Support Services. »
Query for the same:
;WITH SRSSDetailsCTE
AS
(
SELECT
PU.ProductionUnitID,
TTW.WeighingDate,
SOTR.SodiumTreatmentRecipeID ,
(CASE
WHEN TTW.TapTicketWeightTypeID = 1 then TTW.[Weight] END
) AS FullWeight,
(SELECT [Weight] FROM HotMetal.TapTicketWeight TTW WHERE TTW.TapTicketWeightTypeID = 4
AND TTW.TapTicketID = TT.TapTicketID) PreSkimWeight,
((SELECT [Weight] FROM HotMetal.TapTicketWeight TTW WHERE TTW.TapTicketWeightTypeID = 4
AND TTW.TapTicketID = TT.TapTicketID) — (SELECT [Weight] FROM HotMetal.TapTicketWeight TTW WHERE TTW.TapTicketWeightTypeID = 1
AND TTW.TapTicketID = TT.TapTicketID) ) SkimmedWeight,
((SELECT [Weight] FROM HotMetal.TapTicketWeight TTW WHERE TTW.TapTicketWeightTypeID = 1
AND TTW.TapTicketID = TT.TapTicketID) —
(SELECT [Weight] FROM HotMetal.TapTicketWeight TTW WHERE TTW.TapTicketWeightTypeID = 3
AND TTW.TapTicketID = TT.TapTicketID)) NetWeight,
TT.EstimatedWeight,
(CASE
WHEN SOTR.SodiumTreatmentRecipeID=8 then ISNULL(SUM([Weight]),0) END
) AS TotalWeightOfSkimOnlyMetal,
(CASE
WHEN SOTR.SodiumTreatmentRecipeID !=8 then ISNULL(SUM([Weight]),0) END
) AS TotalWeightOfNonSkimOnlyMetal,
(CASE
WHEN SOTR.Code IS NULL then ISNULL(SUM([Weight]),0) END
) AS TotalWeightOfNullRecipeMetal,
(CASE
WHEN SOTR.SodiumTreatmentRecipeID =8 then COUNT(TapTicketNo) END
) AS NoOfSkimOnlyMetal,
(CASE
WHEN SOTR.SodiumTreatmentRecipeID !=8 then COUNT(TapTicketNo) END
) AS NoOfNonSkimOnlyMetal,
(CASE
WHEN SOTR.Code IS NULL then COUNT(TapTicketNo) END
) AS NoOfNullRecipeMetal,
****************TROUBLED Code **********************
ISNULL((select Top 1 numericalValue from ProductionResponse.GetDataPointExtendedValues(
(SELECT
TTW.CreatedDate
FROM HotMetal.TapTicketWeight TTW ,
HotMetal.TapTicketWeightType TTWType
WHERE
TTW.TapTicketID = TT.TapTicketID
AND
TTWType.TapTicketWeightTypeID = TTW.TapTicketWeightTypeID
AND
TTWType.TapTicketWeightTypeID IN (4)
),
(SELECT
TTW.CreatedDate
FROM HotMetal.TapTicketWeight TTW ,
HotMetal.TapTicketWeightType TTWType
WHERE
TTW.TapTicketID = TT.TapTicketID
AND
TTWType.TapTicketWeightTypeID = TTW.TapTicketWeightTypeID
AND
TTWType.TapTicketWeightTypeID IN (1)
),12,HotMetal.GetTemperatureOrALF3Tags(CAST(RTRIM(LTRIM(SUBSTRING(PU_Bay.Code,len(PU_Bay.Code),1))) as NVARCHAR(MAX)),’ALF3′),
NULL )
GROUP BY numericalValue
order by numericalValue desc
), ») AIF3Qty,
***********************************************************************************
FROM
HotMetal.TapTicket TT
LEFT JOIN Potline.Crucible PO on TT.CrucibleID = PO.CrucibleID AND PO.IsActive = 1
LEFT JOIN HotMetal.SodiumTreatmentRecipe SOTR on SOTR.SodiumTreatmentRecipeID = TT.SodiumTreatmentRecipeID
LEFT JOIN HotMetal.TapTicketWeight TTW on TT.TapTicketID = TTW.TapTicketID
JOIN HotMetal.TapTicketWeightType T1 ON TTW.TapTicketWeightTypeID = T1.TapTicketWeightTypeID
LEFT JOIN FurnaceCharge.Batch FBA WITH (INDEX(ukBatchBatchNo)) on FBA.BatchID = TTW.BatchID
LEFT JOIN Equipment.ProductionUnit PU_Bay on PU_Bay.ProductionUnitID = TTW.ScaleProductionUnitID,
Equipment.ProductionUnit PU
WHERE TTW.WeighingDate >= @StartDate
AND TTW.WeighingDate < @EndDate
AND T1.Code in (‘PreSkimming’ , ‘Full’)
)
Select * from SDetailsCTE S
order by S.WeighingDate,S.TapTicketNo desc
OK folks, it did happen at some point, to get this error message: Internal Query Processor Error: The query processor could not produce a query plan. For more information, contact Customer Support Services.
Reproducing the Internal Query Processor Error Message
I was trying to execute the following query:
SELECT * FROM dbo.tbl1 WHERE tbl2ID=(SELECT id FROM dbo.tbl2 WHERE Code='Code1') AND tbl3ID=(SELECT id FROM dbo.tbl3 WHERE Code='Code2')
As you can see, in the above query I’m using two subqueries for getting some keys for use in my main query. In some cases you might get the aforementioned error message. However, this is not always the case as it depends on many factors and not only on the query itself.
Resolving the Internal Query Processor Error Message
Anyway, in order to resolve the issue I just had to re-write the query. The re-written query is the following:
SELECT t1.* FROM dbo.tbl1 t1, dbo.tbl2 t2, dbo.tbl3 t3 WHERE t1.tbl2ID=t2.ID AND t1.tbl3ID=t3.ID AND t2.Code='Code1' AND t3.code='Code2'
As you can see, I just removed the subqueries and replaced them with additional joins on my main query. Now my query works like a charm!
*** Before changing your query or doing anything else, first, make sure that your instance of SQL Server has the latest service pack installed.
Strengthen you SQL Server Development Skills – Enroll to our Online Course!
Check our online course titled “Essential SQL Server Development Tips for SQL Developers”
(special limited-time discount included in link).Via the course, you will sharpen your SQL Server database programming skills via a large set of tips on T-SQL and database development techniques. The course, among other, features over than 30 live demonstrations!
(Lifetime Access/ Live Demos / Downloadable Resources and more!) Enroll from $14.99
Featured Online Courses:
- Essential SQL Server Administration Tips
- SQL Server Fundamentals – SQL Database for Beginners
- Essential SQL Server Development Tips for SQL Developers
- Working with Python on Windows and SQL Server Databases
- Introduction to Computer Programming for Beginners
- Boost SQL Server Database Performance with In-Memory OLTP
- Introduction to Azure SQL Database for Beginners
- .NET Programming for Beginners – Windows Forms with C#
- Introduction to Azure Database for MySQL
- Introduction to SQL Server Machine Learning Services
- SQL Server 2019: What’s New – New and Enhanced Features
- Entity Framework: Getting Started – Complete Beginners Guide
- How to Import and Export Data in SQL Server Databases
- Learn How to Install and Start Using SQL Server in 30 Mins
- A Guide on How to Start and Monetize a Successful Blog
Read Also:
- Essential SQL Server Development Tips for SQL Developers
- The TempDB System Database in SQL Server
- SQL Server Installation and Setup Best Practices
- The feature you are trying to use is on a network resource that is unavailable
- SQL Server 2016: TempDB Enhancements
- tempdb growth
- Introduction to SQL Server Machine Learning Services
- Essential SQL Server Administration Tips
- What are SQL Server Statistics and Where are they Stored?
- How Resolve Error 0xE0434352 in Windows Task Scheduler
- How To Fix the Issue “This device can’t use a Trusted Platform Module”
- …more
Check our other related SQL Server Administration articles.
Subscribe to our newsletter and stay up to date!
Check out our latest software releases!
Check our eBooks!
Rate this article: (2 votes, average: 5.00 out of 5)
Loading…
Reference: SQLNetHub.com (https://www.sqlnethub.com)
© SQLNetHub
Artemakis Artemiou is a Senior SQL Server Architect, Author, a 9 Times Microsoft Data Platform MVP (2009-2018). He has over 20 years of experience in the IT industry in various roles. Artemakis is the founder of SQLNetHub and {essentialDevTips.com}. Artemakis is the creator of the well-known software tools Snippets Generator and DBA Security Advisor. Also, he is the author of many eBooks on SQL Server. Artemakis currently serves as the President of the Cyprus .NET User Group (CDNUG) and the International .NET Association Country Leader for Cyprus (INETA). Moreover, Artemakis teaches on Udemy, you can check his courses here.
Views: 2,766
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit «Cookie Settings» to provide a controlled consent. Read More
Hi all, I have hit a problem in SQL server 2016 and I don’t have access to 2017 to see if the same problem occurs there to. If someone would be so kind as to try the below query in a SQL 2017 environment and report back here I would be very grateful.
In SQL 2016 (SP2-CU3) (KB4458871) — 13.0.5216.0 (X64), Std. Ed., the query results in an error message:
Msg 8624, Level 16, State 17, Line 16
Internal Query Processor Error: The query processor could not produce a query plan. For more information, contact Customer Support Services.
With it a stackdump is created and logged in the sql log. So better not run it in a production environment…
The query has no table requirements and no side effects, so it can be run in any database. This is a very simplified version of an extremely complex query. The crucial part seems to be to generate an xml type in an outer apply, which then gets processed by the .nodes() function.
Here’s the query I would like to hear your results for:
select
(
select top 1
n.e.value('@val','int')
from t2.xmlfragment.nodes('/*') n(e)
)
from (
select 'somevalue'
) t1 (v)
outer apply (
select
t.val as [@val]
from (
select 1 as [val]
) t
for xml path('el'), type
) t2 (xmlfragment)
- This topic was modified 3 years, 10 months ago by R.P.Rozema. Reason: removed order by as it is not needed to reproduce the problem
- This topic was modified 3 years, 10 months ago by R.P.Rozema. Reason: Also union all can be left out and still the dump occurs
Posting Data Etiquette — Jeff Moden[/url]
Posting Performance Based Questions — Gail Shaw[/url]
Hidden RBAR — Jeff Moden[/url]
Cross Tabs and Pivots — Jeff Moden[/url]
Catch-all queries — Gail Shaw[/url]
If you don’t have time to do it right, when will you have time to do it over?
R.P.Rozema
SSChampion
Points: 12305
Using the outer apply is causing this. Replacing it by a cross apply avoids the problem. Now I just need to make sure that I won’t filter out any rows by the cross apply…
Actually I found that this problem exists since at least 2014 in SQL 2008 SP2: https://dba.stackexchange.com/questions/78659/the-query-processor-could-not-produce-a-query-plan
And I was able to reproduce it myself in SQL 2012 too.
Posting Data Etiquette — Jeff Moden[/url]
Posting Performance Based Questions — Gail Shaw[/url]
Hidden RBAR — Jeff Moden[/url]
Cross Tabs and Pivots — Jeff Moden[/url]
Catch-all queries — Gail Shaw[/url]
If you don’t have time to do it right, when will you have time to do it over?
Grant Fritchey
SSC Guru
Points: 398118
Interesting. I just validated that this will fail on SQL Server 2019 as well as SQL Server 2017. The logic of the OUTER APPLY must be somehow invalid. I’m not sure.
In Joyful Craftsmen we provide, among other things, technical support to our customers, which from time to time involves us in very interesting cases. One of them occurred after a migration of a critical stock trading system database to SQL Server 2017. Every night, when there are no trades on the market, a sanitary job runs and deletes old data from some tables in one of its steps. After the migration, this job started to fail with an interesting error message:
Executed as user: DOMAINXYZ. Error: The query processor could not produce a query plan. For more information, contact Customer Support Services. [SQLSTATE 42000] (Error 8624). The step failed.
The error also caused a crash of the thread and a minidump creation:
After some research, we were able to get to the critical part of the code, where the error was occurring:
DELETE TER
FROM [trd].[EntityReferences] AS TER
INNER JOIN [trd].[TransactionBuffers] AS T
ON TER.Id = T.ID AND TER.Type = 10670
WHERE TER.Type = 10670
AND T.Modified < @ToDate
The interesting thing was that the error occurred only when the code had run inside the SQL Server Agent’s job. When we copied the exact same lines of code into SSMS, everything was working properly and the statement finished in a few seconds. As a logical conclusion we tried to align the connection settings of SSMS to the connection options of SQL Server Agent and then the query started to run immediately. This helped us to get the job working but another question arose – why the query had failed with such a strange error under the SQL Server Agent’s connection options?
Connection options vs query optimizer
Before we get to the explanation, let’s have a brief look on what some of these connection options mean and how they are set. The fact that different connectors are using different connection options is pretty well known and on the internet we can find several resources which show differences for most typical connectors. One of them can be found in Erland Sommarskog’s great article Query Plan Mysteries.
ANSI Setting | Applications using ADO .Net, ODBC or OLE DB | SSMS | SQLCMD, OSQL, BCP, SQL Server Agent | ISQL, DB-Library |
ANSI_NULL_DFLT_ON | ON | ON | ON | OFF |
ANSI_NULLS | ON | ON | ON | OFF |
ANSI_PADDING | ON | ON | ON | OFF |
ANSI_WARNINGS | ON | ON | ON | OFF |
CONACT_NULLS_YIELD_NULL | ON | ON | ON | OFF |
QUOTED_IDENTIFIER | ON | ON | OFF | OFF |
ARITHABORT | OFF | ON | OFF | OFF |
In a table taken from Erland’s article I have highlighted two options which differ between SSMS and SQL Server Agent – ARITHABORT and QUOTED_IDENTIFIER.
An ARITHABORT option sets how to handle an overflow or divide-by-zero errors. More specifically, it sets if a number divided by null or zero is a null (when ARITHABORT is OFF) or an error (when ARITHABORT is ON). To make it more complicated this behavior is true only when SET ANSI WARNINGS is OFF. The following diagram visualizes this behavior graphically:
A QUOTED_IDENTIFIER option in simple words means – should a query optimizer consider double quotes as an identifier just as it does for square brackets? All of us know that [] are used in T-SQL to identify keywords or characters against T-SQL syntax. If QUOTED_IDENTIFIER is set to ON, the double quotes will represent the same thing as the square brackets. That’s the reason why both following statements fail:
SET QUOTED_IDENTIFIER ON
GO
SELECT [1]
GO
SELECT “1”
GO
Msg 207, Level 16, State 1, Line 3
Invalid column name ‘1’.
Msg 207, Level 16, State 1, Line 5
Invalid column name ‘1’.
And why the query optimizer for statements
SET QUOTED_IDENTIFIER OFF
GO
SELECT [1]
GO
SELECT “1”
GO
returns an error only for the first one.
By the way, do different connection options for SSMS and SQL Server Agent mean that they are using different drivers to connect to the engine itself? Not at all! As you can see in the following figure, these settings are changed by calling an explicit query statement whenever a new connection is created.
In the first step, SQL Server Agent sets all the connection options during the login phase to “ODBC defaults” which are immediately rewritten by calling set quoted_identifier off. This happens every single time when a new job step opens a connection to SQL Server.
The exact same thing is happening within the SSMS where default driver-based options are also rewritten by a consequent statement as shown in the next figure.
This behavior can be understood in case of SSMS, where the query aligns many settings from a query options dialog, but it really doesn’t make much sense for SQL Server Agent’s connection. Especially when there is no option for how to globally change it.
Root cause
Now that we know how these options are set and what their impact is, let’s focus back on the Internal Query Processor Error. It’s important to say that the table where the delete was performed was something like a crossroads of a database, which linked many tables together. Developers were very conscientious in creating foreign key constraints between all linked tables, which is great for ensuring the integrity of the data but not that useful if you are concerned about performance…
A following figure shows what query plan was generated for that simple delete:
Dozens of relationships for referenced tables mean that for every single row dozens of other tables have to be checked. This is not something that could cause an error by itself, but it led us to the idea of checking the underlying objects in each of the referenced tables. And then we found them…
One of the most discussed things related to connection options are filtered indexes. If you want to create and use them, your connection options have to have QUOTED_IDENTIFIER set to ON. Surprisingly, this information is missing in the documentation for filtered indexes but you can find it in the documentation for QUOTED_IDENTIFIER and for general indexing.
You can display filtered indexes easily by calling:
SELECT * FROM sys.indexes i WHERE i.has_filter = 1
When we crosschecked the output with objects referencing the table where deletion has occurred, we found two filtered indexes. Once we dropped them, the error was gone.
A similar thing could happen with XML indexes as well.
Is it a bug? Under normal circumstances, when you try to perform an operation which would touch a filtered index, you get a nice error message saying “DELETE failed because of SET options”:
USE AdventureWorks2016
GO
SET QUOTED_IDENTIFIER ON;
CREATE NONCLUSTERED INDEX FI_Production_Weight
ON Production.Product ([Weight],[ProductSubcategoryID])
WHERE [Weight] IS NOT NULL;
GO
SET QUOTED_IDENTIFIER OFF;
DELETE
FROM Production.Product
WHERE ProductSubcategoryID = 1;
Msg 1934, Level 16, State 1, Line 10
DELETE failed because the following SET options have incorrect settings: ‘QUOTED_IDENTIFIER’. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
But in our case, when the filtered index was “far” in a tree of referencing tables, a mysterious Internal Query Processor Error appeared instead and the thread crashed. This is definitely not an intended behavior and most likely a bug.
How is this case connected with an upgrade to SQL Server 2017 which I mentioned at the beginning of the post? It isn’t! It just confused us, because the upgrade was connected with some indexes creation (including filtered indexes) from developers and local DBAs didn’t know about it. It’s a good example how Database Lifecycle Management shouldn’t be handled, but that is another story. The important thing is that the connection options for SQL Server Agent remain unchanged in all current versions of SQL Server and an upgrade had nothing to do with the issue we experienced.
Takeaways
A key takeaway is that filtered indexes and T-SQL code inside T-SQL job step in SQL Server Agent don’t play together. Therefore, the first statement in any T-SQL job step should always be SET QUOTED_IDENTIFIER ON. Otherwise we run the risk that the job will fail with a nice or way less nice error message. This is especially true if you are not using stored procedures to execute your code from SQL Server Agent.
If stored procedures or other programmable objects are used (which is good practice anyway), don’t forget to check their connection options by:
WITH c AS (
SELECT OBJECTPROPERTY([object_id], ‘IsQuotedIdentOn’) AS IsQuotedIdentOn, OBJECTPROPERTY([object_id], ‘ExecIsQuotedIdentOn’) AS ExecIsQuotedIdentOn, *
FROM sys.objects o
WHERE o.type NOT IN ( ‘D’, ‘C ‘ )
)
SELECT *
FROM c
WHERE c.IsQuotedIdentOn <> 1
OR c.ExecIsQuotedIdentOn <> 1;
GO
If any rows are returned, check them and try to set proper connection settings for them.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|