Skip to main content

MS SQL Server: Query store fix performance issue

Here are some reference links and script I used to fix performance issue by force query plan using query store feature:

 --https://docs.microsoft.com/en-us/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store?view=sql-server-ver16

--https://www.sqlshack.com/force-query-execution-plan-using-sql-server-2016-query-store/

--ALTER DATABASE [system-abccompany] SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE);

--ALTER DATABASE [system-abccompany] SET QUERY_STORE = ON ( WAIT_STATS_CAPTURE_MODE = 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;

--select count(*) from sys.query_store_query

--ALTER DATABASE [system-abccompany] SET QUERY_STORE (MAX_STORAGE_SIZE_MB =100);

--ALTER DATABASE [system-abccompany] SET QUERY_STORE CLEAR;

--ALTER DATABASE [system-abccompany] SET QUERY_STORE (OPERATION_MODE = READ_WRITE);

--ALTER DATABASE [system-abccompany]  SET QUERY_STORE (OPERATION_MODE = READ_ONLY);


/*check forced plan query

use [system-abccompany]

go

SELECT p.plan_id, p.query_id, q.object_id as containing_object_id,

    force_failure_count, last_force_failure_reason_desc,p.query_plan,p.*

FROM sys.query_store_plan AS p

JOIN sys.query_store_query AS q on p.query_id = q.query_id

WHERE is_forced_plan = 1;

*/

/* find out if the query is captured.

SELECT Txt.query_text_id, Txt.query_sql_text, Pl.plan_id, Qry.*

FROM sys.query_store_plan AS Pl

INNER JOIN sys.query_store_query AS Qry

    ON Pl.query_id = Qry.query_id

INNER JOIN sys.query_store_query_text AS Txt

    ON Qry.query_text_id = Txt.query_text_id

where Txt.query_sql_text like '%SELECT * FROM (SELECT  tblAssignmentStatus%'

*/


-- get the query_id and the good plan_id  which last_duration is good

SELECT qsp.query_id, QSP.plan_id,  QST.query_sql_text, qsq.query_hash, qsp.query_plan_hash, QSRS.last_duration,

QSRS.avg_duration, qsp.query_plan, QSQ.last_execution_time,  -- timezone is not right, show 7 hours ahead, also sometimes it's even less than the first_execution_time

QSRS.first_execution_time,  -- timezone is not right, show 7 hours ahead

QSRS.avg_logical_io_reads,QSRS.avg_logical_io_writes 

FROM sys.query_store_plan AS QSP  JOIN sys.query_store_query AS QSQ      ON QSP.query_id = QSQ.query_id  

JOIN sys.query_store_query_text AS QST      ON QSQ.query_text_id = QST.query_text_id 

JOIN sys.query_store_runtime_stats  QSRS   ON QSP.plan_id =QSRS.plan_id

where QST.query_sql_text like '%SELECT%tblAssignmentStatuses%AssignmentStatusesID%AS%'

order by QSQ.last_execution_time desc


--EXEC sp_query_store_force_plan @query_id = 125, @plan_id = 128


/* is there a forced plan?

SELECT p.query_id

FROM sys.query_store_plan AS p

JOIN sys.query_store_query AS q on p.query_id = q.query_id

WHERE is_forced_plan = 1;

*/

-- stop the plan capture after the good plan is caught.

ALTER DATABASE [system-abccompany]  SET QUERY_STORE (OPERATION_MODE = READ_ONLY);

/*remove redundant query id from query store, method 1, there are still some leftover in query_store_query, you can use method 2 below to remove

DECLARE @id int;

DECLARE adhoc_queries_cursor CURSOR

FOR

    SELECT q.query_id

    FROM sys.query_store_query_text AS qt

    JOIN sys.query_store_query AS q

    ON q.query_text_id = qt.query_text_id

    JOIN sys.query_store_plan AS p

    ON p.query_id = q.query_id

    JOIN sys.query_store_runtime_stats AS rs

    ON rs.plan_id = p.plan_id

    WHERE is_forced_plan <> 1

    ORDER BY q.query_id;

OPEN adhoc_queries_cursor ;

FETCH NEXT FROM adhoc_queries_cursor INTO @id;

WHILE @@fetch_status = 0

BEGIN

    PRINT 'EXEC sp_query_store_remove_query ' + str(@id);

    EXEC sp_query_store_remove_query @id;

    FETCH NEXT FROM adhoc_queries_cursor INTO @id;

END

CLOSE adhoc_queries_cursor;

DEALLOCATE adhoc_queries_cursor;

*/



/*remove redundant query id from query store. method 2, it will delete any query_id that's not using force plan.

DECLARE @id int;

DECLARE adhoc_queries_cursor CURSOR

FOR

    SELECT q.query_id from sys.query_store_query AS q

     WHERE query_id not in

(

SELECT p.query_id

FROM sys.query_store_plan AS p

JOIN sys.query_store_query AS q on p.query_id = q.query_id

WHERE is_forced_plan = 1

)

    ORDER BY q.query_id;

OPEN adhoc_queries_cursor ;

FETCH NEXT FROM adhoc_queries_cursor INTO @id;

WHILE @@fetch_status = 0

BEGIN

    PRINT 'EXEC sp_query_store_remove_query ' + str(@id);

    EXEC sp_query_store_remove_query @id;

    FETCH NEXT FROM adhoc_queries_cursor INTO @id;

END

CLOSE adhoc_queries_cursor;

DEALLOCATE adhoc_queries_cursor;

*/

Comments

Popular posts from this blog

Opatch apply/lsinventory error: oneoff is corrupted or does not exist

I am applying the quarterly patch for 19c RDBMS, I tried using napply but failed, but somehow it corrupted the inventory though nothing applied. further apply and lsinventory command ran into error like this: $ ./OPatch/opatch lsinventory Oracle Interim Patch Installer version 12.2.0.1.21 Copyright (c) 2020, Oracle Corporation.  All rights reserved. Oracle Home       : /u02/app/oracle/19.0.0 Central Inventory : /u01/app/oraInventory    from           : /u02/app/oracle/19.0.0/oraInst.loc OPatch version    : 12.2.0.1.21 OUI version       : 12.2.0.7.0 Log file location : /u02/app/oracle/19.0.0/cfgtoollogs/opatch/opatch2020-09-08_13-35-59PM_1.log Lsinventory Output file location : /u02/app/oracle/19.0.0/cfgtoollogs/opatch/lsinv/lsinventory2020-09-08_13-35-59PM.txt -------------------------------------------------------------------------------- Inventory load failed... OPatch cannot load inventory ...

oracle dba_hist_sysmetric_summary

found this blog is helpful to get CPU and IO statistics on oracle database. http://shob-dbadmin.blogspot.ca/2012/12/how-to-find-total-io-of-database.html courtesy to  Shomil Bansal , below are hist writing, not mine. How to find total IO of the database instance Total IO of database instance is sum of the physical reads, physical writes and redo writes. There are several views to find these values. v$sysmetric  - Reports metric values for only the most current time sample 60 secs. v$sysmetric_summary  - Reports metric values for time sample of 1 hour. v$sysmetric_history  - Reports metric values every 60 sec from the time instance is up. Better way to analyse IO using this view to take deltas between two time periods. dba_hist_sysmetric_history  - All the above views are refreshed when the instance is restarted. This view, part of AWR, stores the historical stats. I have used this view for my report. Query: ====== set lines 350...

ORA_RMAN_SGA_TARGET

assume that we lost all the files of oracle database but we do have rman backup, when trying to bring up a dummy database before restore start, I get this error. RMAN> startup nomount force; WARNING: cannot translate ORA_RMAN_SGA_TARGET value startup failed: ORA-01078: failure in processing system parameters ORA-01565: error in identifying file '+DATA/PROD/spfilePROD.ora' ORA-17503: ksfdopn:2 Failed to open file +DATA/PROD/spfilePROD.ora ORA-15056: additional error message ORA-17503: ksfdopn:DGOpenFile05 Failed to open file +DATA/prod/spfileprod.ora ORA-17503: ksfdopn:2 Failed to open file +DATA/prod/spfileprod.ora ORA-15173: entry 'spfileprod.ora' does not exist in directory 'prod' ORA-06512: at line 4 starting Oracle instance without parameter file for retrival of spfile RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =================================...