2010년 5월 26일 수요일

프로시져 캐쉬 증가 조회

Procedure cache in SQL Server 2005

Posted by decipherinfosys on September 19, 2007


In one of our previous post, we had covered the importance of using bind variables (parameterized queries). In response to that post, one of the readers asked whether it is possible to look at what is available in the memory for the RDBMS. Yes, it is pretty easy to get to that information. In this post, we will cover how to do that in the case of SQL Server 2005 and then will cover Oracle and DB2 LUW in future posts. In the case of SQL Server, memory is used for buffer cache (storing the data) and procedure cache (storing the query plans). The cache is stored as 8KB pages (Oracle has more options on this size). Let’s see how we can find out what is in the procedure cache and how often those plans are getting used.

In SQL Server 2005, there is a DMV that can be used to get this information – the SQL is shown below:

SELECT top 5
name,
type,
(single_pages_kb + multi_pages_kb) AS cache,
entries_count as cnt
FROM sys.dm_os_memory_cache_counters
ORDER BY cache desc

On our test system, this is the output:

name                     type                   cache                cnt
------------------------ ---------------------- -------------------- ------
Object Plans             CACHESTORE_OBJCP       24352                46
Bound Trees              CACHESTORE_PHDR        20648                252
SQL Plans                CACHESTORE_SQLCP       19432                292
TokenAndPermUserStore    USERSTORE_TOKENPERM    14488                31167
SchemaMgr Store          USERSTORE_SCHEMAMGR    10584                0

If you see the output from above, you will see CACHESTORE_OBJCP, CACHESTORE_PHDR and CACHESTORE_SQLCP as the top three cache related enteries. Each has it’s own importance. CACHESTORE_OBJCP represents the compiled plans for stored procedures, triggers and functions, CACHESTORE_SQLCP represents cached SQL statements and batches that are not part of stored procedures/triggers/functions and CACHESTORE_PHDR represents the parsed SQL text. On our test system, we have a few stored procedures that are used by the test harness and there are a lot of dynamic SQL queries that are fired off by the test application that uses an ORM layer. That is why the count for CACHESTORE_OBJCP is 46 and CACHESTORE_SQLCP count is 305.

While I was writing this post, a colleague of mine also pointed out that all this information is also available through the performance monitor. Here is an image that shows you which counter you can use to get that information:

sql_plans.jpg

Once you get the counts, the next logical step is to look for the actual queries that are in the system cache. In order to do that, we will make use of two more DMV’s in SQL Server 2005 and will make use of the new “OUTER APPLY” functionality:

SELECT
cache_plan.objtype,
cache_plan.size_in_bytes,
cache_plan.cacheobjtype,
cache_plan.usecounts,
sql_text.text
FROM sys.dm_exec_cached_plans as cache_plan
outer apply sys.dm_exec_sql_text (cache_plan.plan_handle) as sql_text
ORDER BY cache_plan.usecounts DESC

One can look at the output and see how much space is being occupied by different plans. Since SQL Server does not provide a configuration option to put a cap on the procedure cache, if the application is not using parameterized queries, you will see this cache to be blotted. Hopefully, like Oracle, Microsoft can also provide a configuration option in the future to keep that in check – of course, there is no alternative to a well designed application however, as consultants brought in to tune the environment in production, re-design or fixing the fundamental building blocks of the application is rarely an option that we have.

Procedure Cache Bloating issues – I

Posted by decipherinfosys on December 4, 2008


We had covered in one of our posts before how the usage of non parameterized adhoc SQLs in an application can create performance issues by bloating the procedure cache and lamented the fact that in SQL Server there is no parameter setting to help take control of the cache (unlike Oracle which does provide you a lot of control). You can access those posts here:

So, if you are new to a project and/or you do not know the current application well enough, how can you easily tell whether the applications hitting your production system are running into this issue of procedure cache bloating because of in-efficient code? Use this query to get that information:

SELECT
OBJTYPE AS PLAN_TYPE,
COUNT(*) AS PLAN_NUMBERS,
(SUM(CAST(SIZE_IN_BYTES AS BIGINT))/1024)/1024 AS SIZE_MB,
AVG(USECOUNTS) AS USE_COUNT
FROM SYS.DM_EXEC_CACHED_PLANS
GROUP BY OBJTYPE

PLAN_TYPE            PLAN_NUMBERS SIZE_MB              USE_COUNT
-------------------- --------------- -------------------- -------------
UsrTab 15 0 20
Prepared 8319 891 9
View 694 60 13
Adhoc 28794 1307 6
Check 18 0 17
Trigger 1 0 8
Proc 162 78 134
(7 row(s) affected)

If you see above, you will see that in the PLAN_TYPE of “Adhoc”, the number of plans are huge and they also are taking up the most memory. Their use counts are very low as well. This is a clear indication of the issue that the system is facing. How to fix it? Besides fixing the application to write good parameterized code, you can also looking into the setting the “Forced Parameterization” option in SQL Server 2005. In SQL Server 2008, there is another instance level parameter “Optimize for Adhoc Workloads” which we will cover in Part II of this post.

So, is there any way to stop the bleeding without clearing up the entire cache? There is a way in SQL Server 2005. One can use the following command to clear out the adhoc and prepared plan types but still keep the Proc plan type intact in the cache.

DBCC FREESYSTEMCACHE(‘SQL Plans’)

PLAN_TYPE            PLAN_NUMBERS SIZE_MB              USE_COUNT
-------------------- --------------- -------------------- -------------
UsrTab 15 0 20
View 694 60 13
Adhoc 1 0 1
Check 18 0 17
Trigger 1 0 8
Proc 162 78 134
(6 row(s) affected)

Post the execution of the command, you can see from the output from above, the selective removal of the two enteries in the Procedure Cache. Procedure cache consists of different cache stores and it is possible to selectively remove some of those from the cache. You can read more about the different cache stores and the meta data queries to understand the plan cache behavior at this post on MSDN or this post on sqlteam.com.

Now, once the immediate bleeding has been stopped by running the command, what else can you do – we had mentioned the Forced Parameterization option above. You can set it at the database level by using the “ALTER DATABASE” command or via the GUI as well (search the BOL for Forced Parameterization and you will get the steps to do so). This forces the parameterization for the values in the adhoc SQL queries submitted by the applications. Only under certain scenarios like this one it is advisable not to use parameterization but otherwise in all the OLTP based applications, one should strive to have parameterized queries – the benefits are listed in one of the posts the link of which is given above. This is useful in those scenarios when you are asked to manage a vendor application and do not have much control over the application code – this option as well as plan guides are your best options in those scenarios.

In the next post, we will cover the new SQL Server 2008 parameter which kinda/sorta lets you have some more control on the procedure cache.

2010년 5월 25일 화요일

Procedure 내용으로 검색하기

SELECT routine_name, routine_definition
FROM information_schema.routines
where routine_definition like '%%'

2010년 5월 16일 일요일

SP_READERRORLOG

Problem
O
ne of the issues I have is that the SQL Server Error Log is quite large and it is not always easy to view the contents with the Log File Viewer. In a previous tip "Simple way to find errors in SQL Server error log" you discussed a method of searching the error log using VBScript. Are there any other easy ways to search and find errors in the error log files?

Solution
SQL Server 2005 offers an undocumented system stored procedure sp_readerrorlog. This SP allows you to read the contents of the SQL Server error log files directly from a query window and also allows you to search for certain keywords when reading the error file. This is not new to SQL Server 2005, but this tip discusses how this works for SQL Server 2005.

This is a sample of the stored procedure for SQL Server 2005. You will see that when this gets called it calls an extended stored procedure xp_readerrorlog.

CREATE PROC [sys].[sp_readerrorlog](
@p1 INT = 0,
@p2 INT = NULL,
@p3 VARCHAR(255) = NULL,
@p4 VARCHAR(255) = NULL)
AS
BEGIN

IF
(NOT IS_SRVROLEMEMBER(N'securityadmin') = 1)
BEGIN
RAISERROR
(15003,-1,-1, N'securityadmin')
RETURN (1)
END

IF
(@p2 IS NULL)
EXEC sys.xp_readerrorlog @p1
ELSE
EXEC
sys.xp_readerrorlog @p1,@p2,@p3,@p4
END

This procedure takes four parameters:

  1. Value of error log file you want to read: 0 = current, 1 = Archive #1, 2 = Archive #2, etc...
  2. Log file type: 1 or NULL = error log, 2 = SQL Agent log
  3. Search string 1: String one you want to search for
  4. Search string 2: String two you want to search for to further refine the results

If you do not pass any parameters this will return the contents of the current error log.

Here are a few examples:

Example 1

EXEC sp_readerrorlog 6

This statement returns all of the rows from the 6th archived error log.


Example 2

EXEC sp_readerrorlog 6, 1, '2005'

This returns just 8 rows wherever the value 2005 appears.

Example 3

EXEC sp_readerrorlog 6, 1, '2005', 'exec'

This returns only rows where the value '2005' and 'exec' exist.


xp_readerrrorlog

Even though sp_readerrolog accepts only 4 parameters, the extended stored procedure accepts at least 7 parameters.

If this extended stored procedure is called directly the parameters are as follows:

  1. Value of error log file you want to read: 0 = current, 1 = Archive #1, 2 = Archive #2, etc...
  2. Log file type: 1 or NULL = error log, 2 = SQL Agent log
  3. Search string 1: String one you want to search for
  4. Search string 2: String two you want to search for to further refine the results
  5. Search from start time
  6. Search to end time
  7. Sort order for results: N'asc' = ascending, N'desc' = descending
EXEC master.dbo.xp_readerrorlog 6, 1, '2005', 'exec', NULL, NULL, N'desc'
EXEC master.dbo.xp_readerrorlog 6, 1, '2005', 'exec', NULL, NULL, N'asc'


Next Steps

  • As you can see this is a much easier way to read the error logs and to also look for a specific error message without having to use the Log File Viewer.
  • Add this to your monitoring routine where this is run daily to search for errors or issues.
Readers Who Read This Tip Also Read

2010년 5월 12일 수요일

성능카운트 임계치 참고고

-----------
디스크 튜닝
-----------
[RAID 0]
Physical Disk: Disk Reads/sec + Disk Write/sec / Disk count < 100

[RAID 1]
Physical Disk: Disk Reads/sec + (2 * Disk Write/sec) / 2 < 100

[RAID 10]
Physical Disk: Disk Reads/sec + (2 * Disk Write/sec) / Disk count < 100

[RAID 5]
Physical Disk: Disk Reads/sec + (4 * Disk Write/sec) / Disk count < 100

Physical Disk: Avg. Disk Queue Length
:Avg. Disk Queue Length/Disk Count < 2

Physical Disk: Avg. Disk sec/Read < 15 msec
Physical Disk: Avg. Disk sec/Write < 12 msec

-----------
메모리 튜닝
-----------
Memory: Available MBytes(1MB 1048576Btye)
:프로세스가 실제 사용할 수 있는 메모리양

Memory: Pages/sec
:디스크에서 메모리로 Page in되는 초당 페이지수
이수치가 많다면 SQL Server에 많은 메모리가 할당된 것임.
다른 응용프로그램이 실행되기 위해 페이징발생 우려.
아래의 Stolen Pages와 같이 확인

SQL Server: Buffer Manager: Stolen Pages
:캐시로부터 제거된 페이지수

SQL Server: Memory Manager: Total Server Memory(KB)
:SQL Server가 할당한 전체 메모리양

SQL Server: Memory Manager: Procedure Cache Pages
:컴파일된 쿼리와 저장 프로시저를 저장한 Cache의 페이지수

SQL Server: Buffer Manager: Free Page
:SQL Server가 사용할 수 있는 페이지 수
5MB이상이어야 함. 5MB이하이면 메모리 부족.

SQL Server: Buffer Manager: Buffer Cache Hit Ratio
:90 이상이어야 함

Process: Working Set
:프로세스 내의 스레드가 최근에 사용한 적이 있는 메모리 바이트수
프로세스가 더이상 실행되지 않는데 워킹 셋이 줄지 않으면 프로세스가
메모리를 해제하지 않는 것임(메모리 추가)

Process: Page Faults/sec
:프로세스가 Cache Hit하지 않은 페이지수

-------------
프로세스 튜닝
-------------
Process: % Processor Time < 100

System: Process Queue Length
:프로세서를 얻기위해 프로세서 큐에서 대기한 스레드 수
2 * 프로세스수 < Process Queue Length

System: Context Switches/sec < 10000

----
기타
----
SQL Server: General Statistics: User Connections
:SQL Server의 현재 연결 수

SQL Server: Locks: Lock Timeouts/sec
:Lock Time out에 걸린 잠금 수

SQL Server: Locks: Lock Waits/sec
:잠금대기 요청수

SQL Server: Number of Deadlocks/sec
:데드락 잠금 수
SET DEADLOCK_PRIORITY LOW 설정으로 SQL Server가
데드락 에러(1205) 반환

SQL Server: Memory Manager: Memory Grants Pending
:메모리를 사용하기 위해 대기하고 있는 프로세스 수

SQL Server: Memory Manager: Target Server Memroy(KB)
:SQL Server가 사용할 수 있는 전체 메모리양

SQL Server: Memory Manager: Total Server Memory(KB)
:SQL Server가 사용하고 있는 전체 메모리양

SQL Server: Database: Log Flush Waits/sec
:Log Flush를 대기하는 데이터베이스 커밋수

SQL Server: Database: Percent Log Used
:Log File의 증가, 잘림을 볼 수 있다.