Query Store is configured but none of my queries under any load show up - sql-server-2017

SQL Server 2017 Enterprise Query Store is showing no data at all but shows READ_ONLY as the actual mode
The one similar question in this forum has an answer that doesn't apply - none of the exclusions are present.
I ran:
GO
ALTER DATABASE [MyDB] SET QUERY_STORE (OPERATION_MODE = READ_ONLY, INTERVAL_LENGTH_MINUTES = 5, QUERY_CAPTURE_MODE = AUTO)
GO
I also ran all these, having referenced the link below, DB context is MyDB:
https://learn.microsoft.com/en-us/sql/relational-databases/performance/best-practice-with-the-query-store?view=sql-server-2017
ALTER DATABASE MyDB SET QUERY_STORE = ON;
SELECT actual_state_desc, desired_state_desc, current_storage_size_mb,
max_storage_size_mb, readonly_reason, interval_length_minutes,
stale_query_threshold_days, size_based_cleanup_mode_desc,
query_capture_mode_desc
FROM sys.database_query_store_options;
ALTER DATABASE MyDB SET QUERY_STORE CLEAR;
-- Run together...
ALTER DATABASE MyDB SET QUERY_STORE = OFF;
GO
EXEC sp_query_store_consistency_check
GO
ALTER DATABASE MyDB SET QUERY_STORE = ON;
GO
No issues found. The SELECT returns matching Actual and Desired states.
I am a sysadmin role member, who actually sets up all 30+ production servers, and this is the only miscreant.
The server is under heavy load and I need internal-eyes on it, in addition to Solarwinds DPA. I've also run sp_blitzquerystore but it returns an empty rowset from the top query, and just the two priority 255 rows from the 2nd.
What on earth did I do wrong? Any clues, anyone, please?

I know this is an old post but for those who come here looking for answers: I do see you ran the query with OPERATION_MODE = READ_ONLY. This would put it into a read-only mode - a mode in which it only reads what is stored in the query store without collecting any additional information. There will be no information shown if the query store has never been in READ_WRITE mode.
If it has been in READ_WRITE mode before and you are still not seeing anything, it is possible that the heavy load on the server is pushing query plans out of the cache.

Related

ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE not removing cache?

I have an azure PaaS database and would like to clear cache to test some SP. So I found some scripts from the Internet:
-- run this script against a user database, not master
-- count number of plans currently in cache
select count(*) from sys.dm_exec_cached_plans;
-- Executing this statement will clear the procedure cache in the current database, which means that all queries will have to recompile.
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
-- count number of plans in cache now, after they were cleared from cache
select count(*) from sys.dm_exec_cached_plans;
-- list available plans
select * from sys.dm_exec_cached_plans;
select * from sys.dm_exec_procedure_stats
However, the amount of cache is always around 600-800, so somehow it is not dropping.
I didn't get any error (no permission denied etc), so how this command is not cleaning cache?
I haven't had time to debug through the code to be 100% sure, but based on my understanding of the system it is likely that merely bumping the database schema version (which happens on any alter database command) will invalidate the entries in the cache on next use. Since the procedure cache is instance wide, any attempt to clear the entries associated with the database would need to walk all entries one-by-one instead of merely freeing the whole cache.
So, you can think of this as invalidating the whole cache but lazily removing entries from the cache as they are recompiled or if the memory is reclaimed by other parts of the system through later actions.
Conor Cunningham
Architect, SQL
I contacted Microsoft support and understood it now.
Try to run the following T-SQL on AdventureWorks database.
-- create test procedure
create or alter procedure pTest1
as begin
select * from salesLT.product where ProductCategoryID =27
end
go
-- exec the procedure once.
exec pTest1
-- check for cached plan for this specific procedure - cached plan exists
select * from sys.dm_exec_cached_plans p
cross apply sys.dm_exec_sql_text(p.plan_handle) st
where p.objtype = 'proc' and st.objectid = OBJECT_ID('pTest1')
-- clear plan cache
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
-- check for cached plan for this specific procedure - not exists anymore
select * from sys.dm_exec_cached_plans p
cross apply sys.dm_exec_sql_text(p.plan_handle) st
where p.objtype = 'proc' and st.objectid = OBJECT_ID('pTest1')
-- cleanup
drop procedure pTest1
select 'cleanup complete'
with this sample, we can confirm that plan cache is cleared for the database, however, sys.dm_exec_cached_plans is server wide and give you results from other databases as well (internal system databases) that for them the cache was not cleared with the CLEAR PROCEDURE_CACHE command.

Query against a view under master database is much slower than query directly under specific database

I am not sure whether there exists a general answer before I give more details.
For exmaple: I have a view named vw_View
I tried the following two queries to get the result:
Under master database select * From [test].[dbo].[vw_View]
Under test database select * From [dbo].[vw_View]
Could anyone tell me why query against the same query but from master database is much slower than query against from the other databases, I even tried the others by:
Use [db] --any other databases not master database
select * From [test].[dbo].[vw_View]
I have checked the actual execution plan, the join order differs but why it will change since I have already specify [test].[dbo].[vw_View] when under master
Just out of curiosity, thanks in advance.
Note this might not be the answer but it was too much text for a comment anyway...
One thing that we hear about a lot is when the developers complain about a slow running procedure which only runs slow when called from the application but runs fine when executing from the SSMS.
More often than not it is due to the different execution settings depending on from where the procedure is being called. To check if there is a difference in those setting I usually use SQL Profiler.
In your case you can open two different windows in the SSMS one in the context of Master database and the other in the context of the User Database and run SQL Profiler, the very first event profiler will capture, will be the Event Class = Existing Connections and Text Data = -- network protocol: LPC......
This record will show you all the default settings for each session where your are executing the commands, The settings would look something like....
-- network protocol: LPC
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
Now compare the settings of both sessions and see what are the differences.
The profiler also has a column SIPD which will help you to identify which window is which. I am pretty sure the answer is around somewhere there.
Have the same issue - executing a view from master goes infinitely long, but executing the same view "under any other user database on this server" goes only 8 sec.
I have an environment where we just migrated to SQL Server 2017 and "all other databases" have Compatibility Level = 2008 (or 2012)
So I did a few tests:
If I create a new DB with default Compatibility Level = 2017 and run the query it executes infinitely long
If I change Compatibility Level to 2008 and reconnect - 8 sec
If I change Compatibility Level back to 2017 - long run again
And the final thing we have noticed about the query itself - the query is using CHARINDEX function and if I comment it out the query executes equally 8 sec for both compatibility levels.
So... it looks like we have an mixed issue with CHARINDEX function execution on legacy database under Compatibility Level = 2017 context.
The solution is (if you can call it this way...) - to execute legacy queries under (the same) legacy execution context.

Script for creating database if it doesn't exist yet in SQL Azure

This question may related to Checking if database exists or not in SQL Azure.
In SQL Azure, I tried to use a script like this to check the existence of a database, and create the database if it doesn't exist yet (in both SQLCmd and SSMS):
IF db_id('databasename') IS NULL CREATE DATABASE databasename
GO
However, SQL Azure keeps telling me
Msg 40530, Level 16, State 1, Line 2
The CREATE DATABASE statement must be the only statement in the batch.
While the same script did work on a local SQL express instance.
Does this mean it is not supported on SQL Azure?
Or is there any work around?
Thanks in advance.
Eidt:
Let me clarify what I want to achieve:
I want a script which will create a certain database only if it doesn't exist before.
Is it possible to have such kind of script for SQL Azure?
We have a similar problem.
It looks like we can do something with SET NOEXEC ON, as in the following StackExchange answer.
IF (<condition>)
SET NOEXEC ON
ELSE
SET NOEXEC OFF
GO
CREATE DATABASE databasename
GO
SET NOEXEC OFF
GO
It's saying you can't do theck and create in the same piece of sql.
i.e you need to do Select IF db_id('databasename')
test the whether it returns null, and if so then execute the create database.

Stored procedure will not display in object explorer?

USE [MASTER]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
USE [MASTER]
GO
CREATE PROCEDURE [dbo].[TOTALLY_NEW] #FISCAL_YEAR NVARCHAR(4) AS
BEGIN
PRINT 'HERE'
END
GO
select * from master..sysobjects
where name like 'tot%' <-- returns one row!!!!!!
I've refreshed this list a dozen times..!!
I've tried disconnecting and reconnecting..
I've created all those other SP's listed in the image before.
Here is a picture with more.
Ensure that the user you are using has permissions to view stored procedures. I am not 100% on SQL Server which permission this is but I have seen this problem on a few other databases where a user creates a SP, but another user does not have permission to view or list the SPs.
Per request, converting comment to answer:
Yes, you shouldn't be creating user objects in master. The only time I ever do it is when I explicitly want to create a utility procedure that I can call from any database using that database's context, which you have to do on purpose and doesn't happen by accident - so I suspect you inadvertently marked your object as a system procedure. You do this using EXEC sp_MS_marksystemobject (or in older versions by having set EXEC sp_MS_upd_sysobj_category 1 - the latter might work in 2005 with 80 compatibility, not sure).

UPDATE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'

I am having a problem with an update stored procedure. The error is:
UPDATE 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 query notifications and/or xml data type methods.
SQL State: 42000
Native Error: 1934
Unfortunately, there are no indexed views, computed columns, or query notifications for this table. This Stored Procedure was running fine for past couple of days and since today has been returning this error.
Is there any suggestion that would help in identifying the problem?
Note: If I set the quoted_identifier to ON and rerun the CREATE PROCEDURE, the issue will be fixed (for now). But I want to understand what triggered this issue in the first place.
To avoid that error, I needed to add
SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
for all my stored procs editing a table with a computed column.
You don't need to add the SET inside the proc, just use it during creation, like this:
SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
GO
CREATE PROCEDURE dbo.proc_myproc
...
I got this error when I tried to run an sql file via the command line with sqlcmd:
sqlcmd -i myfile.sql
By default QUOTED_IDENTIFIER is set to OFF when using this command line tool and you will get the same error (no matter that in the SSMS it may be set to ON and the same script will pass).
So indeed the solution is to add this QUOTED_IDENTIFIER ON to your sql file like Jim suggested, or explicitly specify the flag -I:
sqlcmd -i myfile.sql -I
We cannot create a indexed view by setting the quoted identifier off. I just tried it and SQL 2005 throws an error straight away if it is turned off:
Cannot create index. Object 'SmartListVW' was created with the following SET options off: 'QUOTED_IDENTIFIER'.
As gbn said, rebuilding the indexes must be the only other way it got turned off.
I have seen lots of articles saying it must be on before creating index on views. Otherwise you would get an error while inserting, updating the table, but here I can get the error straight away, so sql engine won't allow to create index on views by setting it to off, per this msdn link.
I have asked a similar question here in stack sometime ago...
EDIT
I turned off the global queryexecution (in editor) ANSI settings and ran the index script in new editor, this time also it throws the same error. So it's clear we can't create indexes on views by turning off quoted_identifier.
I'm late to this party but had this error and wanted to share it.
Our problem was recurrent but random so we knew it wasn't an object that had been created incorrectly.
We finally tracked it down to an ODBC connection on one of the servers in our Citrix farm. On that server, the ODBC in question had had its QUOTED_IDENTIFIERS turned off (unchecked). On all the other servers, it was checked as expected. We turned the option on and the problem was instantly solved.
I got this error when I run SQL Agent Job, which has 3 steps T-sql scripts.
Msg 1934, Sev 16, State 1, Line 15 : UPDATE 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. [SQLSTATE 42000]
I added
SET ANSI_NULLS, QUOTED_IDENTIFIER ON; to the top of the Agent Job and that solved the issue.
Some thoughts:
Did indexes get rebuilt? If you do index maintenance using DMO, then quoted_identifier will not always be preserved. It can be a pain to track down and was a particular problem is SQL Server 2000 until SP4 or so.
However, I've seen on SQL Server 2005 some time ago too.
SELECT
OBJECT_NAME (sm.object_id) AS [Name],
sm.uses_ansi_nulls,
sm.uses_quoted_identifier,
N'SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
--change the below CREATE to an ALTER.
GO
' + sm.definition AS PossibleFixingStatement
FROM
sys.sql_modules AS sm
WHERE
1 = 1
AND
(
sm.uses_ansi_nulls <> 1
OR sm.uses_quoted_identifier <> 1
)
AND NOT EXISTS
(
SELECT
*
FROM
sys.objects AS o
WHERE
o.is_ms_shipped = 1
AND o.object_id = sm.[object_id]
)
ORDER BY
sm.uses_ansi_nulls,
sm.uses_quoted_identifier;
Query to identify the affected objects. Part of the sp_blitz procedure mentioned here at https://github.com/BrentOzarULTD/SQL-Server-First-Responder-Kit/issues/1698
I got this error today running a stored procedure in SSMS. Disconnecting from the server and reconnecting with a new session solved the problem for me. The SP I was running had never had this problem before.
I got the same error running this query in the Job Scheduler SQL Server Agent
UPDATE [Order]
SET OrderStatusID = 100
WHERE OrderStatusID = 200
AND OrderID IN (
[...]
)
I solved removing the [ ] characters from [Order]:
UPDATE Order
SET OrderStatusID = 100
WHERE OrderStatusID = 200
AND OrderID IN (
[...]
)
No more errors
I got the same error, had to add a couple of settings to get it resolved:
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET NUMERIC_ROUNDABORT OFF;
SET QUOTED_IDENTIFIER OFF;
SET NOCOUNT ON;