2010. 8. 23. 15:33

RML Utilities for SQL Server

'Common Admin' 카테고리의 다른 글

waitresource 값 확인  (0) 2010.11.01
MCITP 취득 방법  (0) 2010.10.06
SQL 2008 -New DataType-Date  (0) 2010.06.04
SQLDMO  (0) 2010.06.04
2010. 8. 17. 18:03

SQL 2008:: 삭제 레지스터리


SQL Server 2008


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQLSERVER
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MsDtsServer100

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SQL Server.



SQL Server 2008 수동으로 제거

setup.exe  /SQL /INSTANCENAME = MSSQLSERVER

SQL Server 2008 수동으로 제거하려면 다음과 같이 하십시오.
  1. 명령 프롬프트에서 다음 명령을 입력한 다음 Enter 키를 누릅니다.
    CD %ProgramFiles%\Microsoft SQL Server\100\Setup Bootstrap\Release
  2. 다음 명령을 입력한 다음 Enter 키를 누릅니다.
    /ACTION setup.exe = 제거/FEATURES Feature_List/INSTANCENAME = Instance_Name =
    참고 이 명령은 Feature_List 자리 "AS, SQL, RS, 도구." 등의 기능 값이 없는 공간, 쉼표로 구분된 목록을 나타냅니다. Instance_Name 자리 설치된 SQL Server 2008의 명명된 인스턴스를 나타냅니다. 명명된 인스턴스를 사용하지 않은 경우, 명명된 인스턴스에 대해 "MSSQLSERVER" 사용할 수 있습니다.

http://support.microsoft.com/kb/955404/ko

'Install /Setup' 카테고리의 다른 글

SQL 2012 Intergration Service 구성 항목 설정  (0) 2014.08.21
Install Tip  (0) 2010.06.04
SQL Server 수동 시작  (1) 2010.01.22
2010. 7. 19. 14:50

[T-SQL] JOb 수행 시간 완료 계산

SQL Server 2005 이상

1. JOB의 수행 완료 시간 계산



SELECT  a.name,  b.run_date, convert(varchar(4),run_time/10000) + ':' + convert(varchar(4),run_time/100%100) + ':' + convert(varchar(4),run_time%100) as run_time
		,convert(varchar(4),run_duration/10000) + ':' + convert(varchar(4),run_duration/100%100) + ':' + convert(varchar(4),run_duration%100) as run_duration
		,convert(int, (run_duration/10000 * 3600 ) + ((run_duration/100%100) * 60) + (run_duration%100 )) as duration_sec
		,convert(DATETIME, RTRIM(run_date)) +  (run_time * 9 + run_time % 10000 * 6 + run_time % 100 * 10) / 216e4 as start_date
		,dateadd(ss, convert(int, (run_duration/10000 * 3600 ) + ((run_duration/100%100) * 60) + (run_duration%100 ))
					,CONVERT(DATETIME, RTRIM(run_date)) +  (run_time * 9 + run_time % 10000 * 6 + run_time % 100 * 10) / 216e4 ) as end_date
FROM msdb.dbo.sysjobs as a with (nolock)
	inner join msdb.dbo.sysjobhistory as b with (nolock)  on a.job_id = b.job_id
where 
	--and b.job_id = ''
	b.run_date >= 20100709 and b.run_date < 20100719
	and b.step_id = 0
order by b.run_date, b.run_time



2. JOB 스케줄 조회



select
    j.job_id
,   J.name
,   S.name as '일정'
,	CASE S.freq_type WHEN 1 THEN '한번만'
			WHEN 4 THEN '매일'
			WHEN 8 THEN '매주'
			WHEN 16 THEN '매월'
			WHEN 32 THEN '매월 상대적'
			WHEN 64 THEN 'SQL Server Agent가 시작될때 실행' 
	END as freq_type 
,   s.freq_interval
,   CASE S.freq_subday_type
        WHEN 1 THEN '지정된시간'
        WHEN 2 THEN '초'
        WHEN 4 THEN '분'
        WHEN 8 THEN '시간'
    END AS freq_subday_type
,	S.freq_subday_interval         
,	right('00000' + cast(S.active_start_time as varchar), 6) as '시작시간'
,	right('00000' + cast(S.active_end_time as varchar), 6) as '끝시간'
,	S.active_start_date as 'job 시작일'
,	S.active_end_date as 'job 종료일'
from msdb.dbo.sysjobs J LEFT JOIN sysjobschedules as A on a.job_id = J.job_id
    JOIN msdb.dbo.sysschedules S WITH (NOLOCK) ON A.schedule_id = S.schedule_id
where J.enabled = 1
order by J.name, right('00000' + cast(S.active_start_time as varchar), 6) asc



3. 해당 시간에 실행되는 JOB 


--=======================================
-- 해당 시간에 실행되는  JOB 
-- =======================================
select  J.name
	, S.last_run_date
	, convert(char(10), S.last_run_time, 114) as 'last_run_start_time'
	,S.last_run_time + S.last_run_duration as 'last_run_end_time', S.last_run_duration as 'duration_time'
from msdb.dbo.sysjobservers S with (nolock)
  inner join msdb.dbo.sysjobs J with (nolock) on S.job_id = J.job_id
where S.last_run_date = '20081202'
-- 작업 시간 입력
and ( (S.last_run_time between '000000' and '010000' ) or
	(S.last_run_time + S.last_run_duration >= '000000' and S.last_run_time + S.last_run_duration < '010000'))
	and J.enabled = 1
order by J.name


select j.job_id, j.name, h.step_id
	, sum(case when  h.run_status = 1 then 1 else 0 end) as '성공count'
	, sum(case when  h.run_status = 0 then 1 else 0 end) as '실패count'
	 ,max(h.run_date) as run_date, max(h.run_time) as run_time 
	, max((CONVERT ( DATETIME, RTRIM(run_date)) 
		+  ( run_time * 9 + run_time % 10000 * 6  + run_time % 100 * 10  + 25 * run_duration ) / 216e4  ) )  as 종료시간	 
from msdb.dbo.sysjobhistory as h with (nolock)
	join msdb.dbo.sysjobs as j with (nolock) on h.job_id = j.job_id
where run_date = '20100412'
	and run_time >= '210000'
group by j.job_id, j.name, h.step_id
order by j.job_id, h.step_id



'T-SQL' 카테고리의 다른 글

T-SQL:: INDEX-중복인덱스 제거.  (1) 2011.08.13
DBCC ShrinkFile  (0) 2010.09.06
Index::Defrag Script v4.0  (0) 2010.06.15
T_SQL::미 사용 Table  (0) 2010.06.15
2010. 6. 15. 06:51

Index::Defrag Script v4.0

SQL SERVER 2008 SP 2 이상


출처: http://sqlfool.com/category/sql-scripts/

인덱스 조각화를 얻고 실행하는 sp 이다.
SQLl 2005의 sp2 이상에서 가능하다.


1. 테이블 생성
/* Scroll down to the see notes, disclaimers, and licensing information */
 
DECLARE @indexDefragLog_rename      VARCHAR(128)
    , @indexDefragExclusion_rename  VARCHAR(128)
    , @indexDefragStatus_rename     VARCHAR(128);
 
SELECT @indexDefragLog_rename       = 'dba_indexDefragLog_obsolete_' + CONVERT(VARCHAR(10), GETDATE(), 112)
    , @indexDefragExclusion_rename  = 'dba_indexDefragExclusion_obsolete_' + CONVERT(VARCHAR(10), GETDATE(), 112)
    , @indexDefragStatus_rename     = 'dba_indexDefragStatus_obsolete_' + CONVERT(VARCHAR(10), GETDATE(), 112);
 
IF Exists(SELECT [OBJECT_ID] FROM sys.tables WHERE [name] = 'dba_indexDefragLog')
    EXECUTE SP_RENAME dba_indexDefragLog, @indexDefragLog_rename;
 
IF Exists(SELECT [OBJECT_ID] FROM sys.tables WHERE [name] = 'dba_indexDefragExclusion')
    EXECUTE SP_RENAME dba_indexDefragExclusion, @indexDefragExclusion_rename;
 
IF Exists(SELECT [OBJECT_ID] FROM sys.tables WHERE [name] = 'dba_indexDefragStatus')
    EXECUTE SP_RENAME dba_indexDefragStatus, @indexDefragStatus_rename;
Go
 
CREATE TABLE dbo.dba_indexDefragLog
(
      indexDefrag_id    INT IDENTITY(1,1)   Not Null
    , databaseID        INT                 Not Null
    , databaseName      NVARCHAR(128)       Not Null
    , objectID          INT                 Not Null
    , objectName        NVARCHAR(128)       Not Null
    , indexID           INT                 Not Null
    , indexName         NVARCHAR(128)       Not Null
    , partitionNumber   SMALLINT            Not Null
    , fragmentation     FLOAT               Not Null
    , page_count        INT                 Not Null
    , dateTimeStart     DATETIME            Not Null
    , dateTimeEnd       DATETIME            Null
    , durationSeconds   INT                 Null
    , sqlStatement      VARCHAR(4000)       Null
    , errorMessage      VARCHAR(1000)       Null
 
    CONSTRAINT PK_indexDefragLog_v40
        PRIMARY KEY CLUSTERED (indexDefrag_id)
);
 
PRINT 'dba_indexDefragLog Table Created';
 
CREATE TABLE dbo.dba_indexDefragExclusion
(
      databaseID        INT                 Not Null
    , databaseName      NVARCHAR(128)       Not Null
    , objectID          INT                 Not Null
    , objectName        NVARCHAR(128)       Not Null
    , indexID           INT                 Not Null
    , indexName         NVARCHAR(128)       Not Null
    , exclusionMask     INT                 Not Null
        /* 1=Sunday, 2=Monday, 4=Tuesday, 8=Wednesday, 16=Thursday, 32=Friday, 64=Saturday */
 
    CONSTRAINT PK_indexDefragExclusion_v40
        PRIMARY KEY CLUSTERED (databaseID, objectID, indexID)
);
 
PRINT 'dba_indexDefragExclusion Table Created';
 
CREATE TABLE dbo.dba_indexDefragStatus
(
      databaseID        INT
    , databaseName      NVARCHAR(128)
    , objectID          INT
    , indexID           INT
    , partitionNumber   SMALLINT
    , fragmentation     FLOAT
    , page_count        INT
    , range_scan_count  BIGINT
    , schemaName        NVARCHAR(128)   Null
    , objectName        NVARCHAR(128)   Null
    , indexName         NVARCHAR(128)   Null
    , scanDate          DATETIME        
    , defragDate        DATETIME        Null
    , printStatus       BIT             DEFAULT(0)
    , exclusionMask     INT             DEFAULT(0)
 
    CONSTRAINT PK_indexDefragStatus_v40
        PRIMARY KEY CLUSTERED(databaseID, objectID, indexID, partitionNumber)
);
 
PRINT 'dba_indexDefragStatus Table Created';
2. 프로시저 생성
--===================
-- proc
--===================
 
IF OBJECTPROPERTY(OBJECT_ID('dbo.dba_indexDefrag_sp'), N'IsProcedure') = 1
BEGIN
    DROP PROCEDURE dbo.dba_indexDefrag_sp;
    PRINT 'Procedure dba_indexDefrag_sp dropped';
END;
Go
 
CREATE PROCEDURE dbo.dba_indexDefrag_sp
 
    /* Declare Parameters */
      @minFragmentation     FLOAT           = 10.0  
        /* in percent, will not defrag if fragmentation less than specified */
    , @rebuildThreshold     FLOAT           = 30.0  
        /* in percent, greater than @rebuildThreshold will result in rebuild instead of reorg */
    , @executeSQL           BIT             = 1     
        /* 1 = execute; 0 = print command only */
    , @defragOrderColumn    NVARCHAR(20)    = 'range_scan_count'
        /* Valid options are: range_scan_count, fragmentation, page_count */
    , @defragSortOrder      NVARCHAR(4)     = 'DESC'
        /* Valid options are: ASC, DESC */
    , @timeLimit            INT             = 720 /* defaulted to 12 hours */
        /* Optional time limitation; expressed in minutes */
    , @DATABASE             VARCHAR(128)    = Null
        /* Option to specify a database name; null will return all */
    , @tableName            VARCHAR(4000)   = Null  -- databaseName.schema.tableName
        /* Option to specify a table name; null will return all */
    , @forceRescan          BIT             = 0
        /* Whether or not to force a rescan of indexes; 1 = force, 0 = use existing scan, if available */
    , @scanMode             VARCHAR(10)     = N'LIMITED'
        /* Options are LIMITED, SAMPLED, and DETAILED */
    , @minPageCount         INT             = 8 
        /*  MS recommends > 1 extent (8 pages) */
    , @maxPageCount         INT             = Null
        /* NULL = no limit */
    , @excludeMaxPartition  BIT             = 0
        /* 1 = exclude right-most populated partition; 0 = do not exclude; see notes for caveats */
    , @onlineRebuild        BIT             = 1     
        /* 1 = online rebuild; 0 = offline rebuild; only in Enterprise */
    , @sortInTempDB         BIT             = 1
        /* 1 = perform sort operation in TempDB; 0 = perform sort operation in the index's database */
    , @maxDopRestriction    TINYINT         = Null
        /* Option to restrict the number of processors for the operation; only in Enterprise */
    , @printCommands        BIT             = 0     
        /* 1 = print commands; 0 = do not print commands */
    , @printFragmentation   BIT             = 0
        /* 1 = print fragmentation prior to defrag; 
           0 = do not print */
    , @defragDelay          CHAR(8)         = '00:00:05'
        /* time to wait between defrag commands */
    , @debugMode            BIT             = 0
        /* display some useful comments to help determine if/where issues occur */
 
AS
/*********************************************************************************
    Name:       dba_indexDefrag_sp
 
    Author:     Michelle Ufford, http://sqlfool.com
 
    Purpose:    Defrags one or more indexes for one or more databases
 
    Notes:
 
    CAUTION: TRANSACTION LOG SIZE SHOULD BE MONITORED CLOSELY WHEN DEFRAGMENTING.
             DO NOT RUN UNATTENDED ON LARGE DATABASES DURING BUSINESS HOURS.
 
      @minFragmentation     defaulted to 10%, will not defrag if fragmentation 
                            is less than that
 
      @rebuildThreshold     defaulted to 30% as recommended by Microsoft in BOL;
                            greater than 30% will result in rebuild instead
 
      @executeSQL           1 = execute the SQL generated by this proc; 
                            0 = print command only
 
      @defragOrderColumn    Defines how to prioritize the order of defrags.  Only
                            used if @executeSQL = 1.  
                            Valid options are: 
                            range_scan_count = count of range and table scans on the
                                               index; in general, this is what benefits 
                                               the most from defragmentation
                            fragmentation    = amount of fragmentation in the index;
                                               the higher the number, the worse it is
                            page_count       = number of pages in the index; affects
                                               how long it takes to defrag an index
 
      @defragSortOrder      The sort order of the ORDER BY clause.
                            Valid options are ASC (ascending) or DESC (descending).
 
      @timeLimit            Optional, limits how much time can be spent performing 
                            index defrags; expressed in minutes.
 
                            NOTE: The time limit is checked BEFORE an index defrag
                                  is begun, thus a long index defrag can exceed the
                                  time limitation.
 
      @database             Optional, specify specific database name to defrag;
                            If not specified, all non-system databases will
                            be defragged.
 
      @tableName            Specify if you only want to defrag indexes for a 
                            specific table, format = databaseName.schema.tableName;
                            if not specified, all tables will be defragged.
 
      @forceRescan          Whether or not to force a rescan of indexes.  If set
                            to 0, a rescan will not occur until all indexes have
                            been defragged.  This can span multiple executions.
                            1 = force a rescan
                            0 = use previous scan, if there are indexes left to defrag
 
      @scanMode             Specifies which scan mode to use to determine
                            fragmentation levels.  Options are:
                            LIMITED - scans the parent level; quickest mode,
                                      recommended for most cases.
                            SAMPLED - samples 1% of all data pages; if less than
                                      10k pages, performs a DETAILED scan.
                            DETAILED - scans all data pages.  Use great care with
                                       this mode, as it can cause performance issues.
 
      @minPageCount         Specifies how many pages must exist in an index in order 
                            to be considered for a defrag.  Defaulted to 8 pages, as 
                            Microsoft recommends only defragging indexes with more 
                            than 1 extent (8 pages).  
 
                            NOTE: The @minPageCount will restrict the indexes that
                            are stored in dba_indexDefragStatus table.
 
      @maxPageCount         Specifies the maximum number of pages that can exist in 
                            an index and still be considered for a defrag.  Useful
                            for scheduling small indexes during business hours and
                            large indexes for non-business hours.
 
                            NOTE: The @maxPageCount will restrict the indexes that
                            are defragged during the current operation; it will not
                            prevent indexes from being stored in the 
                            dba_indexDefragStatus table.  This way, a single scan
                            can support multiple page count thresholds.
 
      @excludeMaxPartition  If an index is partitioned, this option specifies whether
                            to exclude the right-most populated partition.  Typically,
                            this is the partition that is currently being written to in
                            a sliding-window scenario.  Enabling this feature may reduce
                            contention.  This may not be applicable in other types of 
                            partitioning scenarios.  Non-partitioned indexes are 
                            unaffected by this option.
                            1 = exclude right-most populated partition
                            0 = do not exclude
 
      @onlineRebuild        1 = online rebuild; 
                            0 = offline rebuild
 
      @sortInTempDB         Specifies whether to defrag the index in TEMPDB or in the
                            database the index belongs to.  Enabling this option may
                            result in faster defrags and prevent database file size 
                            inflation.
                            1 = perform sort operation in TempDB
                            0 = perform sort operation in the index's database 
 
      @maxDopRestriction    Option to specify a processor limit for index rebuilds
 
      @printCommands        1 = print commands to screen; 
                            0 = do not print commands
 
      @printFragmentation   1 = print fragmentation to screen;
                            0 = do not print fragmentation
 
      @defragDelay          Time to wait between defrag commands; gives the
                            server a little time to catch up 
 
      @debugMode            1 = display debug comments; helps with troubleshooting
                            0 = do not display debug comments
 
    Called by:  SQL Agent Job or DBA
 
    ----------------------------------------------------------------------------
    DISCLAIMER: 
    This code and information are provided "AS IS" without warranty of any kind,
    either expressed or implied, including but not limited to the implied 
    warranties or merchantability and/or fitness for a particular purpose.
    ----------------------------------------------------------------------------
    LICENSE: 
    This index defrag script is free to download and use for personal, educational, 
    and internal corporate purposes, provided that this header is preserved. 
    Redistribution or sale of this index defrag script, in whole or in part, is 
    prohibited without the author's express written consent.
    ----------------------------------------------------------------------------
    Date        Initials	Version Description
    ----------------------------------------------------------------------------
    2007-12-18  MFU         1.0     Initial Release
    2008-10-17  MFU         1.1     Added @defragDelay, CIX_temp_indexDefragList
    2008-11-17  MFU         1.2     Added page_count to log table
                                    , added @printFragmentation option
    2009-03-17  MFU         2.0     Provided support for centralized execution
                                    , consolidated Enterprise & Standard versions
                                    , added @debugMode, @maxDopRestriction
                                    , modified LOB and partition logic  
    2009-06-18  MFU         3.0     Fixed bug in LOB logic, added @scanMode option
                                    , added support for stat rebuilds (@rebuildStats)
                                    , support model and msdb defrag
                                    , added columns to the dba_indexDefragLog table
                                    , modified logging to show "in progress" defrags
                                    , added defrag exclusion list (scheduling)
    2009-08-28  MFU         3.1     Fixed read_only bug for database lists
    2010-04-20  MFU         4.0     Added time limit option
                                    , added static table with rescan logic
                                    , added parameters for page count & SORT_IN_TEMPDB
                                    , added try/catch logic and additional debug options
                                    , added options for defrag prioritization
                                    , fixed bug for indexes with allow_page_lock = off
                                    , added option to exclude right-most partition
                                    , removed @rebuildStats option
                                    , refer to http://sqlfool.com for full release notes
*********************************************************************************
    Example of how to call this script:
 
        Exec dbo.dba_indexDefrag_sp
              @executeSQL           = 1
            , @printCommands        = 1
            , @debugMode            = 1
            , @printFragmentation   = 1
            , @forceRescan          = 1
            , @maxDopRestriction    = 1
            , @minPageCount         = 8
            , @maxPageCount         = Null
            , @minFragmentation     = 1
            , @rebuildThreshold     = 30
            , @defragDelay          = '00:00:05'
            , @defragOrderColumn    = 'page_count'
            , @defragSortOrder      = 'DESC'
            , @excludeMaxPartition  = 1
            , @timeLimit            = Null;
*********************************************************************************/																
SET NOCOUNT ON;
SET XACT_Abort ON;
SET Quoted_Identifier ON;
 
BEGIN
 
    BEGIN Try
 
        /* Just a little validation... */
        IF @minFragmentation IS Null 
            Or @minFragmentation Not Between 0.00 And 100.0
                SET @minFragmentation = 10.0;
 
        IF @rebuildThreshold IS Null
            Or @rebuildThreshold Not Between 0.00 And 100.0
                SET @rebuildThreshold = 30.0;
 
        IF @defragDelay Not Like '00:[0-5][0-9]:[0-5][0-9]'
            SET @defragDelay = '00:00:05';
 
        IF @defragOrderColumn IS Null
            Or @defragOrderColumn Not In ('range_scan_count', 'fragmentation', 'page_count')
                SET @defragOrderColumn = 'range_scan_count';
 
        IF @defragSortOrder IS Null
            Or @defragSortOrder Not In ('ASC', 'DESC')
                SET @defragSortOrder = 'DESC';
 
        IF @scanMode Not In ('LIMITED', 'SAMPLED', 'DETAILED')
            SET @scanMode = 'LIMITED';
 
        IF @debugMode IS Null
            SET @debugMode = 0;
 
        IF @forceRescan IS Null
            SET @forceRescan = 0;
 
        IF @sortInTempDB IS Null
            SET @sortInTempDB = 1;
 
 
        IF @debugMode = 1 RAISERROR('Undusting the cogs and starting up...', 0, 42) WITH NoWait;
 
        /* Declare our variables */
        DECLARE   @objectID                 INT
                , @databaseID               INT
                , @databaseName             NVARCHAR(128)
                , @indexID                  INT
                , @partitionCount           BIGINT
                , @schemaName               NVARCHAR(128)
                , @objectName               NVARCHAR(128)
                , @indexName                NVARCHAR(128)
                , @partitionNumber          SMALLINT
                , @fragmentation            FLOAT
                , @pageCount                INT
                , @sqlCommand               NVARCHAR(4000)
                , @rebuildCommand           NVARCHAR(200)
                , @dateTimeStart            DATETIME
                , @dateTimeEnd              DATETIME
                , @containsLOB              BIT
                , @editionCheck             BIT
                , @debugMessage             NVARCHAR(4000)
                , @updateSQL                NVARCHAR(4000)
                , @partitionSQL             NVARCHAR(4000)
                , @partitionSQL_Param       NVARCHAR(1000)
                , @LOB_SQL                  NVARCHAR(4000)
                , @LOB_SQL_Param            NVARCHAR(1000)
                , @indexDefrag_id           INT
                , @startDateTime            DATETIME
                , @endDateTime              DATETIME
                , @getIndexSQL              NVARCHAR(4000)
                , @getIndexSQL_Param        NVARCHAR(4000)
                , @allowPageLockSQL         NVARCHAR(4000)
                , @allowPageLockSQL_Param   NVARCHAR(4000)
                , @allowPageLocks           INT
                , @excludeMaxPartitionSQL   NVARCHAR(4000);
 
        /* Initialize our variables */
        SELECT @startDateTime = GETDATE()
            , @endDateTime = DATEADD(MINUTE, @timeLimit, GETDATE());
 
        /* Create our temporary tables */
        CREATE TABLE #databaseList
        (
              databaseID        INT
            , databaseName      VARCHAR(128)
            , scanStatus        BIT
        );
 
        CREATE TABLE #processor 
        (
              [INDEX]           INT
            , Name              VARCHAR(128)
            , Internal_Value    INT
            , Character_Value   INT
        );
 
        CREATE TABLE #maxPartitionList
        (
              databaseID        INT
            , objectID          INT
            , indexID           INT
            , maxPartition      INT
        );
 
        IF @debugMode = 1 RAISERROR('Beginning validation...', 0, 42) WITH NoWait;
 
        /* Make sure we're not exceeding the number of processors we have available */
        INSERT INTO #processor
        EXECUTE XP_MSVER 'ProcessorCount';
 
        IF @maxDopRestriction IS Not Null And @maxDopRestriction > (SELECT Internal_Value FROM #processor)
            SELECT @maxDopRestriction = Internal_Value
            FROM #processor;
 
        /* Check our server version; 1804890536 = Enterprise, 610778273 = Enterprise Evaluation, -2117995310 = Developer */
        IF (SELECT SERVERPROPERTY('EditionID')) In (1804890536, 610778273, -2117995310) 
            SET @editionCheck = 1 -- supports online rebuilds
        ELSE
            SET @editionCheck = 0; -- does not support online rebuilds
 
        /* Output the parameters we're working with */
        IF @debugMode = 1 
        BEGIN
 
            SELECT @debugMessage = 'Your selected parameters are... 
            Defrag indexes with fragmentation greater than ' + CAST(@minFragmentation AS VARCHAR(10)) + ';
            Rebuild indexes with fragmentation greater than ' + CAST(@rebuildThreshold AS VARCHAR(10)) + ';
            You' + CASE WHEN @executeSQL = 1 THEN ' DO' ELSE ' DO NOT' END + ' want the commands to be executed automatically; 
            You want to defrag indexes in ' + @defragSortOrder + ' order of the ' + UPPER(@defragOrderColumn) + ' value;
            You have' + CASE WHEN @timeLimit IS Null THEN ' not specified a time limit;' ELSE ' specified a time limit of ' 
                + CAST(@timeLimit AS VARCHAR(10)) END + ' minutes;
            ' + CASE WHEN @DATABASE IS Null THEN 'ALL databases' ELSE 'The ' + @DATABASE + ' database' END + ' will be defragged;
            ' + CASE WHEN @tableName IS Null THEN 'ALL tables' ELSE 'The ' + @tableName + ' table' END + ' will be defragged;
            We' + CASE WHEN Exists(SELECT TOP 1 * FROM dbo.dba_indexDefragStatus WHERE defragDate IS Null)
                And @forceRescan <> 1 THEN ' WILL NOT' ELSE ' WILL' END + ' be rescanning indexes;
            The scan will be performed in ' + @scanMode + ' mode;
            You want to limit defrags to indexes with' + CASE WHEN @maxPageCount IS Null THEN ' more than ' 
                + CAST(@minPageCount AS VARCHAR(10)) ELSE
                ' between ' + CAST(@minPageCount AS VARCHAR(10))
                + ' and ' + CAST(@maxPageCount AS VARCHAR(10)) END + ' pages;
            Indexes will be defragged' + CASE WHEN @editionCheck = 0 Or @onlineRebuild = 0 THEN ' OFFLINE;' ELSE ' ONLINE;' END + '
            Indexes will be sorted in' + CASE WHEN @sortInTempDB = 0 THEN ' the DATABASE' ELSE ' TEMPDB;' END + '
            Defrag operations will utilize ' + CASE WHEN @editionCheck = 0 Or @maxDopRestriction IS Null 
                THEN 'system defaults for processors;' 
                ELSE CAST(@maxDopRestriction AS VARCHAR(2)) + ' processors;' END + '
            You' + CASE WHEN @printCommands = 1 THEN ' DO' ELSE ' DO NOT' END + ' want to print the ALTER INDEX commands; 
            You' + CASE WHEN @printFragmentation = 1 THEN ' DO' ELSE ' DO NOT' END + ' want to output fragmentation levels; 
            You want to wait ' + @defragDelay + ' (hh:mm:ss) between defragging indexes;
            You want to run in' + CASE WHEN @debugMode = 1 THEN ' DEBUG' ELSE ' SILENT' END + ' mode.';
 
            RAISERROR(@debugMessage, 0, 42) WITH NoWait;
 
        END;
 
        IF @debugMode = 1 RAISERROR('Grabbing a list of our databases...', 0, 42) WITH NoWait;
 
        /* Retrieve the list of databases to investigate */
        INSERT INTO #databaseList
        SELECT database_id
            , name
            , 0 -- not scanned yet for fragmentation
        FROM sys.databases
        WHERE name = IsNull(@DATABASE, name)
            And [name] Not In ('master', 'tempdb')-- exclude system databases
            And [STATE] = 0 -- state must be ONLINE
            And is_read_only = 0;  -- cannot be read_only
 
        /* Check to see if we have indexes in need of defrag; otherwise, re-scan the database(s) */
        IF Not Exists(SELECT TOP 1 * FROM dbo.dba_indexDefragStatus WHERE defragDate IS Null)
            Or @forceRescan = 1
        BEGIN
 
            /* Truncate our list of indexes to prepare for a new scan */
            TRUNCATE TABLE dbo.dba_indexDefragStatus;
 
            IF @debugMode = 1 RAISERROR('Looping through our list of databases and checking for fragmentation...', 0, 42) WITH NoWait;
 
            /* Loop through our list of databases */
            WHILE (SELECT COUNT(*) FROM #databaseList WHERE scanStatus = 0) > 0
            BEGIN
 
                SELECT TOP 1 @databaseID = databaseID
                FROM #databaseList
                WHERE scanStatus = 0;
 
                SELECT @debugMessage = '  working on ' + DB_NAME(@databaseID) + '...';
 
                IF @debugMode = 1
                    RAISERROR(@debugMessage, 0, 42) WITH NoWait;
 
               /* Determine which indexes to defrag using our user-defined parameters */
                INSERT INTO dbo.dba_indexDefragStatus
                (
                      databaseID
                    , databaseName
                    , objectID
                    , indexID
                    , partitionNumber
                    , fragmentation
                    , page_count
                    , range_scan_count
                    , scanDate
                )
                SELECT
                      ps.database_id AS 'databaseID'
                    , QUOTENAME(DB_NAME(ps.database_id)) AS 'databaseName'
                    , ps.OBJECT_ID AS 'objectID'
                    , ps.index_id AS 'indexID'
                    , ps.partition_number AS 'partitionNumber'
                    , SUM(ps.avg_fragmentation_in_percent) AS 'fragmentation'
                    , SUM(ps.page_count) AS 'page_count'
                    , os.range_scan_count
                    , GETDATE() AS 'scanDate'
                FROM sys.dm_db_index_physical_stats(@databaseID, OBJECT_ID(@tableName), Null , Null, @scanMode) AS ps
                Join sys.dm_db_index_operational_stats(@databaseID, OBJECT_ID(@tableName), Null , Null) AS os
                    ON ps.database_id = os.database_id
                    And ps.OBJECT_ID = os.OBJECT_ID
                    and ps.index_id = os.index_id
                    And ps.partition_number = os.partition_number
                WHERE avg_fragmentation_in_percent >= @minFragmentation 
                    And ps.index_id > 0 -- ignore heaps
                    And ps.page_count > @minPageCount 
                    And ps.index_level = 0 -- leaf-level nodes only, supports @scanMode
                GROUP BY ps.database_id 
                    , QUOTENAME(DB_NAME(ps.database_id)) 
                    , ps.OBJECT_ID 
                    , ps.index_id 
                    , ps.partition_number 
                    , os.range_scan_count
                OPTION (MaxDop 2);
 
                /* Do we want to exclude right-most populated partition of our partitioned indexes? */
                IF @excludeMaxPartition = 1
                BEGIN
 
                    SET @excludeMaxPartitionSQL = '
                        Select ' + CAST(@databaseID AS VARCHAR(10)) + ' As [databaseID]
                            , [object_id]
                            , index_id
                            , Max(partition_number) As [maxPartition]
                        From ' + DB_NAME(@databaseID) + '.sys.partitions
                        Where partition_number > 1
                            And [rows] > 0
                        Group By object_id
                            , index_id;';
 
                    INSERT INTO #maxPartitionList
                    EXECUTE SP_EXECUTESQL @excludeMaxPartitionSQL;
 
                END;
 
                /* Keep track of which databases have already been scanned */
                UPDATE #databaseList
                SET scanStatus = 1
                WHERE databaseID = @databaseID;
 
            END
 
            /* We don't want to defrag the right-most populated partition, so
               delete any records for partitioned indexes where partition = Max(partition) */
            IF @excludeMaxPartition = 1
            BEGIN
 
                DELETE ids
                FROM dbo.dba_indexDefragStatus AS ids
                Join #maxPartitionList AS mpl
                    ON ids.databaseID = mpl.databaseID
                    And ids.objectID = mpl.objectID
                    And ids.indexID = mpl.indexID
                    And ids.partitionNumber = mpl.maxPartition;
 
            END;
 
            /* Update our exclusion mask for any index that has a restriction on the days it can be defragged */
            UPDATE ids
            SET ids.exclusionMask = ide.exclusionMask
            FROM dbo.dba_indexDefragStatus AS ids
            Join dbo.dba_indexDefragExclusion AS ide
                ON ids.databaseID = ide.databaseID
                And ids.objectID = ide.objectID
                And ids.indexID = ide.indexID;
 
        END
 
        SELECT @debugMessage = 'Looping through our list... there are ' + CAST(COUNT(*) AS VARCHAR(10)) + ' indexes to defrag!'
        FROM dbo.dba_indexDefragStatus
        WHERE defragDate IS Null
            And page_count Between @minPageCount And IsNull(@maxPageCount, page_count);
 
        IF @debugMode = 1 RAISERROR(@debugMessage, 0, 42) WITH NoWait;
 
        /* Begin our loop for defragging */
        WHILE (SELECT COUNT(*) 
               FROM dbo.dba_indexDefragStatus 
               WHERE (
                           (@executeSQL = 1 And defragDate IS Null) 
                        Or (@executeSQL = 0 And defragDate IS Null And printStatus = 0)
                     )
                And exclusionMask & POWER(2, DATEPART(weekday, GETDATE())-1) = 0
                And page_count Between @minPageCount And IsNull(@maxPageCount, page_count)) > 0
        BEGIN
 
            /* Check to see if we need to exit our loop because of our time limit */        
            IF IsNull(@endDateTime, GETDATE()) < GETDATE()
            BEGIN
                RAISERROR('Our time limit has been exceeded!', 11, 42) WITH NoWait;
            END;
 
            IF @debugMode = 1 RAISERROR('  Picking an index to beat into shape...', 0, 42) WITH NoWait;
 
            /* Grab the index with the highest priority, based on the values submitted; 
               Look at the exclusion mask to ensure it can be defragged today */
            SET @getIndexSQL = N'
            Select Top 1 
                  @objectID_Out         = objectID
                , @indexID_Out          = indexID
                , @databaseID_Out       = databaseID
                , @databaseName_Out     = databaseName
                , @fragmentation_Out    = fragmentation
                , @partitionNumber_Out  = partitionNumber
                , @pageCount_Out        = page_count
            From dbo.dba_indexDefragStatus
            Where defragDate Is Null ' 
                + CASE WHEN @executeSQL = 0 THEN 'And printStatus = 0' ELSE '' END + '
                And exclusionMask & Power(2, DatePart(weekday, GetDate())-1) = 0
                And page_count Between @p_minPageCount and IsNull(@p_maxPageCount, page_count)
            Order By + ' + @defragOrderColumn + ' ' + @defragSortOrder;
 
            SET @getIndexSQL_Param = N'@objectID_Out        int OutPut
                                     , @indexID_Out         int OutPut
                                     , @databaseID_Out      int OutPut
                                     , @databaseName_Out    nvarchar(128) OutPut
                                     , @fragmentation_Out   int OutPut
                                     , @partitionNumber_Out int OutPut
                                     , @pageCount_Out       int OutPut
                                     , @p_minPageCount      int
                                     , @p_maxPageCount      int';
 
            EXECUTE SP_EXECUTESQL @getIndexSQL
                , @getIndexSQL_Param
                , @p_minPageCount       = @minPageCount
                , @p_maxPageCount       = @maxPageCount
                , @objectID_Out         = @objectID OUTPUT
                , @indexID_Out          = @indexID OUTPUT
                , @databaseID_Out       = @databaseID OUTPUT
                , @databaseName_Out     = @databaseName OUTPUT
                , @fragmentation_Out    = @fragmentation OUTPUT
                , @partitionNumber_Out  = @partitionNumber OUTPUT
                , @pageCount_Out        = @pageCount OUTPUT;
 
            IF @debugMode = 1 RAISERROR('  Looking up the specifics for our index...', 0, 42) WITH NoWait;
 
            /* Look up index information */
            SELECT @updateSQL = N'Update ids
                Set schemaName = QuoteName(s.name)
                    , objectName = QuoteName(o.name)
                    , indexName = QuoteName(i.name)
                From dbo.dba_indexDefragStatus As ids
                Inner Join ' + @databaseName + '.sys.objects As o
                    On ids.objectID = o.object_id
                Inner Join ' + @databaseName + '.sys.indexes As i
                    On o.object_id = i.object_id
                    And ids.indexID = i.index_id
                Inner Join ' + @databaseName + '.sys.schemas As s
                    On o.schema_id = s.schema_id
                Where o.object_id = ' + CAST(@objectID AS VARCHAR(10)) + '
                    And i.index_id = ' + CAST(@indexID AS VARCHAR(10)) + '
                    And i.type > 0
                    And ids.databaseID = ' + CAST(@databaseID AS VARCHAR(10));
 
            EXECUTE SP_EXECUTESQL @updateSQL;
 
            /* Grab our object names */
            SELECT @objectName  = objectName
                , @schemaName   = schemaName
                , @indexName    = indexName
            FROM dbo.dba_indexDefragStatus
            WHERE objectID = @objectID
                And indexID = @indexID
                And databaseID = @databaseID;
 
            IF @debugMode = 1 RAISERROR('  Grabbing the partition count...', 0, 42) WITH NoWait;
 
            /* Determine if the index is partitioned */
            SELECT @partitionSQL = 'Select @partitionCount_OUT = Count(*)
                                        From ' + @databaseName + '.sys.partitions
                                        Where object_id = ' + CAST(@objectID AS VARCHAR(10)) + '
                                            And index_id = ' + CAST(@indexID AS VARCHAR(10)) + ';'
                , @partitionSQL_Param = '@partitionCount_OUT int OutPut';
 
            EXECUTE SP_EXECUTESQL @partitionSQL, @partitionSQL_Param, @partitionCount_OUT = @partitionCount OUTPUT;
 
            IF @debugMode = 1 RAISERROR('  Seeing if there are any LOBs to be handled...', 0, 42) WITH NoWait;
 
            /* Determine if the table contains LOBs */
            SELECT @LOB_SQL = ' Select @containsLOB_OUT = Count(*)
                                From ' + @databaseName + '.sys.columns With (NoLock) 
                                Where [object_id] = ' + CAST(@objectID AS VARCHAR(10)) + '
                                   And (system_type_id In (34, 35, 99)
                                            Or max_length = -1);'
                                /*  system_type_id --> 34 = image, 35 = text, 99 = ntext
                                    max_length = -1 --> varbinary(max), varchar(max), nvarchar(max), xml */
                    , @LOB_SQL_Param = '@containsLOB_OUT int OutPut';
 
            EXECUTE SP_EXECUTESQL @LOB_SQL, @LOB_SQL_Param, @containsLOB_OUT = @containsLOB OUTPUT;
 
            IF @debugMode = 1 RAISERROR('  Checking for indexes that do not allow page locks...', 0, 42) WITH NoWait;
 
            /* Determine if page locks are allowed; for those indexes, we need to always rebuild */
            SELECT @allowPageLockSQL = 'Select @allowPageLocks_OUT = Count(*)
                                        From ' + @databaseName + '.sys.indexes
                                        Where object_id = ' + CAST(@objectID AS VARCHAR(10)) + '
                                            And index_id = ' + CAST(@indexID AS VARCHAR(10)) + '
                                            And Allow_Page_Locks = 0;'
                , @allowPageLockSQL_Param = '@allowPageLocks_OUT int OutPut';
 
            EXECUTE SP_EXECUTESQL @allowPageLockSQL, @allowPageLockSQL_Param, @allowPageLocks_OUT = @allowPageLocks OUTPUT;
 
            IF @debugMode = 1 RAISERROR('  Building our SQL statements...', 0, 42) WITH NoWait;
 
            /* If there's not a lot of fragmentation, or if we have a LOB, we should reorganize */
            IF (@fragmentation < @rebuildThreshold Or @containsLOB >= 1 Or @partitionCount > 1)
                And @allowPageLocks = 0
            BEGIN
 
                SET @sqlCommand = N'Alter Index ' + @indexName + N' On ' + @databaseName + N'.' 
                                    + @schemaName + N'.' + @objectName + N' ReOrganize';
 
                /* If our index is partitioned, we should always reorganize */
                IF @partitionCount > 1
                    SET @sqlCommand = @sqlCommand + N' Partition = ' 
                                    + CAST(@partitionNumber AS NVARCHAR(10));
 
            END
            /* If the index is heavily fragmented and doesn't contain any partitions or LOB's, 
               or if the index does not allow page locks, rebuild it */
            ELSE IF (@fragmentation >= @rebuildThreshold Or @allowPageLocks <> 0)
                And IsNull(@containsLOB, 0) != 1 And @partitionCount <= 1
            BEGIN
 
                /* Set online rebuild options; requires Enterprise Edition */
                IF @onlineRebuild = 1 And @editionCheck = 1 
                    SET @rebuildCommand = N' Rebuild With (Online = On';
                ELSE
                    SET @rebuildCommand = N' Rebuild With (Online = Off';
 
                /* Set sort operation preferences */
                IF @sortInTempDB = 1 
                    SET @rebuildCommand = @rebuildCommand + N', Sort_In_TempDB = On';
                ELSE
                    SET @rebuildCommand = @rebuildCommand + N', Sort_In_TempDB = Off';
 
                /* Set processor restriction options; requires Enterprise Edition */
                IF @maxDopRestriction IS Not Null And @editionCheck = 1
                    SET @rebuildCommand = @rebuildCommand + N', MaxDop = ' + CAST(@maxDopRestriction AS VARCHAR(2)) + N')';
                ELSE
                    SET @rebuildCommand = @rebuildCommand + N')';
 
                SET @sqlCommand = N'Alter Index ' + @indexName + N' On ' + @databaseName + N'.'
                                + @schemaName + N'.' + @objectName + @rebuildCommand;
 
            END
            ELSE
                /* Print an error message if any indexes happen to not meet the criteria above */
                IF @printCommands = 1 Or @debugMode = 1
                    RAISERROR('We are unable to defrag this index.', 0, 42) WITH NoWait;
 
            /* Are we executing the SQL?  If so, do it */
            IF @executeSQL = 1
            BEGIN
 
                SET @debugMessage = 'Executing: ' + @sqlCommand;
 
                /* Print the commands we're executing if specified to do so */
                IF @printCommands = 1 Or @debugMode = 1
                    RAISERROR(@debugMessage, 0, 42) WITH NoWait;
 
                /* Grab the time for logging purposes */
                SET @dateTimeStart  = GETDATE();
 
                /* Log our actions */
                INSERT INTO dbo.dba_indexDefragLog
                (
                      databaseID
                    , databaseName
                    , objectID
                    , objectName
                    , indexID
                    , indexName
                    , partitionNumber
                    , fragmentation
                    , page_count
                    , dateTimeStart
                    , sqlStatement
                )
                SELECT
                      @databaseID
                    , @databaseName
                    , @objectID
                    , @objectName
                    , @indexID
                    , @indexName
                    , @partitionNumber
                    , @fragmentation
                    , @pageCount
                    , @dateTimeStart
                    , @sqlCommand;
 
                SET @indexDefrag_id = SCOPE_IDENTITY();
 
                /* Wrap our execution attempt in a try/catch and log any errors that occur */
                BEGIN Try
 
                    /* Execute our defrag! */
                    EXECUTE SP_EXECUTESQL @sqlCommand;
                    SET @dateTimeEnd = GETDATE();
 
                    /* Update our log with our completion time */
                    UPDATE dbo.dba_indexDefragLog
                    SET dateTimeEnd = @dateTimeEnd
                        , durationSeconds = DATEDIFF(SECOND, @dateTimeStart, @dateTimeEnd)
                    WHERE indexDefrag_id = @indexDefrag_id;
 
                END Try
                BEGIN Catch
 
                    /* Update our log with our error message */
                    UPDATE dbo.dba_indexDefragLog
                    SET dateTimeEnd = GETDATE()
                        , durationSeconds = -1
                        , errorMessage = Error_Message()
                    WHERE indexDefrag_id = @indexDefrag_id;
 
                    IF @debugMode = 1 
                        RAISERROR('  An error has occurred executing this command! Please review the dba_indexDefragLog table for details.'
                            , 0, 42) WITH NoWait;
 
                END Catch
 
                /* Just a little breather for the server */
                WAITFOR Delay @defragDelay;
 
                UPDATE dbo.dba_indexDefragStatus
                SET defragDate = GETDATE()
                    , printStatus = 1
                WHERE databaseID       = @databaseID
                  And objectID         = @objectID
                  And indexID          = @indexID
                  And partitionNumber  = @partitionNumber;
 
            END
            ELSE
            /* Looks like we're not executing, just printing the commands */
            BEGIN
                IF @debugMode = 1 RAISERROR('  Printing SQL statements...', 0, 42) WITH NoWait;
 
                IF @printCommands = 1 Or @debugMode = 1 
                    PRINT IsNull(@sqlCommand, 'error!');
 
                UPDATE dbo.dba_indexDefragStatus
                SET printStatus = 1
                WHERE databaseID       = @databaseID
                  And objectID         = @objectID
                  And indexID          = @indexID
                  And partitionNumber  = @partitionNumber;
            END
 
        END
 
        /* Do we want to output our fragmentation results? */
        IF @printFragmentation = 1
        BEGIN
 
            IF @debugMode = 1 RAISERROR('  Displaying a summary of our action...', 0, 42) WITH NoWait;
 
            SELECT databaseID
                , databaseName
                , objectID
                , objectName
                , indexID
                , indexName
                , partitionNumber
                , fragmentation
                , page_count
                , range_scan_count
            FROM dbo.dba_indexDefragStatus
            WHERE defragDate >= @startDateTime
            ORDER BY defragDate;
 
        END;
 
    END Try
    BEGIN Catch
 
        SET @debugMessage = Error_Message() + ' (Line Number: ' + CAST(Error_Line() AS VARCHAR(10)) + ')';
        PRINT @debugMessage;
 
    END Catch;
 
    /* When everything is said and done, make sure to get rid of our temp table */
    DROP TABLE #databaseList;
    DROP TABLE #processor;
    DROP TABLE #maxPartitionList;
 
    IF @debugMode = 1 RAISERROR('DONE!  Thank you for taking care of your indexes!  :)', 0, 42) WITH NoWait;
 
    SET NOCOUNT OFF;
    RETURN 0
END


4. 사용법
 Exec dbo.dba_indexDefrag_sp
              @executeSQL           = 0
            , @printCommands        = 1
            , @DATABASE             ='search'
            --, @tableName            =
            , @debugMode            = 1
            , @printFragmentation   = 1
            , @forceRescan          = 1
            , @maxDopRestriction    = 1
            , @minPageCount         = 8
            , @maxPageCount         = Null
            , @minFragmentation     = 1
            , @rebuildThreshold     = 30
            , @defragDelay          = '00:00:05'
            , @defragOrderColumn    = 'page_count'
            , @defragSortOrder      = 'DESC'
            , @excludeMaxPartition  = 1
            , @timeLimit            = Null;



'T-SQL' 카테고리의 다른 글

DBCC ShrinkFile  (0) 2010.09.06
[T-SQL] JOb 수행 시간 완료 계산  (0) 2010.07.19
T_SQL::미 사용 Table  (0) 2010.06.15
데이터베이스 사이즈  (0) 2010.06.04
2010. 6. 15. 06:27

T_SQL::미 사용 Table


미사용 Table 목록


SELECT  idx.object_id, OBJECT_NAME(IDX.object_id) as object_name,
        max(ps.row_count) as row_count,
        max(obj.create_date) as create_date,
        max(obj.modify_date) as modify_date
FROM sys.dm_db_index_usage_stats  AS DIS
       RIGHT OUTER JOIN sys.indexes AS IDX  ON DIS.object_id = IDX.object_id AND DIS.index_id = IDX.index_id
       JOIN sys.objects AS OBJ  ON IDX.object_id = OBJ.object_ID
       JOIN sys.dm_db_partition_stats as PS ON ps.object_id = OBJ.object_id
WHERE  OBJ.type IN ('U', 'V') AND DIS.object_id IS NULL
GROUP BY idx.object_id
ORDER BY OBJECT_NAME(IDX.object_id)

'T-SQL' 카테고리의 다른 글

[T-SQL] JOb 수행 시간 완료 계산  (0) 2010.07.19
Index::Defrag Script v4.0  (0) 2010.06.15
데이터베이스 사이즈  (0) 2010.06.04
T-SQL::Removing Duplication Data  (1) 2010.06.03
2010. 6. 10. 00:40

네할렘 아키텍쳐

http://ko.wikipedia.org/wiki/%EB%84%A4%ED%95%A0%EB%A0%98_%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98

http://brown.ezphp.net/58


피망(게임) 서비스에 네할렘 서버를 적용해 본 결과, 초당 쿼리가 2750개를 처리해 기존(하퍼타운)보다 2배의 성능 향상을 보였습니다. 이는 서버를 절반 이상 감축할 수 있음을 의미합니다."

'ETC' 카테고리의 다른 글

Admin::Superdome VS DL580 G7  (0) 2011.01.10
믹시 가입  (0) 2010.10.13
최상위 코어 i7 프로세서를 낳은 인텔 네할렘 아키텍처  (0) 2010.06.10
유틸::엑셀이용 데이터 입력  (1) 2010.06.03
2010. 6. 10. 00:34

최상위 코어 i7 프로세서를 낳은 인텔 네할렘 아키텍처

'ETC' 카테고리의 다른 글

믹시 가입  (0) 2010.10.13
네할렘 아키텍쳐  (0) 2010.06.10
유틸::엑셀이용 데이터 입력  (1) 2010.06.03
Active Directory Management  (0) 2009.09.16
2010. 6. 7. 23:57

Admin::SQL Server Trace Flags


flag Trace Flag Description (underlined are sp_configure’able)
-1 Sets trace flags for all connections. Used only with DBCC TRACEON and TRACEOFF. The setting of the Trace flag -1 is not visible with DBCC TRACESTATUS command, but work without problems.
105 SQL Server 6.5 you can use maximum 16 tables or subqueries in a single select statement. There is no documented way, to avoid this restriction, but you can use undocumented trace flag 105 for this purpose.
106 Disables line number information for syntax errors.
107 Interprets numbers with a decimal point as float instead of decimal.
110 Turns off ANSI select characteristics.
204 A backward compatibility switch that enables non-ansi standard behavior. E.g. previously SQL server ignored trailing blanks in the like statement and allowed queries that contained aggregated functions to have items in the group by clause that were not in the select list.
205 Report when a statistics-dependent stored procedure is being recompiled as a result of AutoStat.
206 Provides backward compatibility for the setuser statement.
208 SET QUOTED IDENTIFIER ON.
237 Tells SQL Server to use correlated sub-queries in Non-ANSI standard backward compatibility mode.
242 Provides backward compatibility for correlated subqueries where non-ANSI-standard results are desired.
243 The behavior of SQL Server is now more consistent because null ability checks are made at run time and a null ability violation results in the command terminating and the batch or transaction process continuing.
244 Disables checking for allowed interim constraint violations. By default, SQL Server checks for and allows interim constraint violations. An interim constraint violation is caused by a change that removes the violation such that the constraint is met, all within a single statement and transaction. SQL Server checks for interim constraint violations for self-referencing DELETE statements, INSERT, and multi-row UPDATE statements. This checking requires more work tables. With this trace flag you can disallow interim constraint violations, thus requiring fewer work tables.
246 Derived or NULL columns must be explicitly named in a select….INTO or create view statement when not done they raise an error. This flag avoids that.
253 Prevents ad-hoc query plans to stay in cache.
257 Will invoke a print algorithm on the XML output before returning it to make the XML result more readable.
260 Prints versioning information about extended stored procedure dynamic-link libraries (DLLs). For more information about __GetXpVersion(), see Creating Extended Stored Procedures. Scope: global or session
262 SQL 7 - Trailing spaces are no longer truncated from literal strings in CASE statements. Used after hotfix 891116
302 Should be used with flag 310 to show the actual join ordering. Prints information about whether the statistics page is used, the actual selectivity (if available), and what SQL Server estimated the physical and logical I/O would be for the indexes.
310 Prints information about join order. Index selection information is also available in a more readable format using SET SHOWPLAN_ALL, as described in the SET statement.
320 Disables join-order heuristics used in ANSI joins. To see join-order heuristics use flag 310. SQL Server uses join-order heuristics to reduce the no’ of permutations when using the best join order.
323 Reports on the use of update statements using UPDATE in place. Shows a detailed description of the various update methods used by SQL Server 6.5.
325 Prints information about the cost of using a non-clustered index or a sort to process an ORDER BY clause.
326 Prints information about the estimated & actual costs of sorts. Instructs the server to use arithmetic averaging when calculating density instead of a geometric weighted average when updating statistics.  Useful for building better stats when an index has skew on the leading column.  Use only for updating the stats of a table/index with known skewed data.
330 Enables full output when using the SET SHOWPLAN_ALL option, which gives detailed information about joins.
342 Disables the costing of pseudo-merge joins, thus significantly reducing time spent on the parse for certain types of large, multi-table joins. One can also use SET FORCEPLAN ON to disable the costing of pseudo-merge joins because the query is forced to use the order specified in the FROM clause.
345 Increase the accuracy of choice of optimum order when you join 6 or more tables.
506 Enforces SQL-92 standards regarding null values for comparisons between variables and parameters. Any comparison of variables and parameters that contain a NULL always results in a NULL.
610

SQL 10 – Enable the potential for minimal-logging when:

·   Bulk loading into an empty clustered index, with no nonclustered indexes

·   Bulk loading into a non-empty heap, with no nonclustered indexes

611 After SQL 9 when turned on, each lock escalation is recorded in the SQL Server error log along with the SQL Server handle number.
652 Disables read ahead for the server.
653 Disables read ahead for the current connection.
661 Disables the ghost record removal process. A ghost record is the result of a delete operation. When you delete a record, the deleted record is kept as a ghost record. Later, the deleted record is purged by the ghost record removal process. When you disable this process, the deleted record is not purged. Therefore, the space that the deleted record consumes is not freed. This behavior affects space consumption and the performance of scan operations. SCOPE: Global. If you turn off this trace flag, the ghost record removal process works correctly.
806 Cause 'DBCC-style' page auditing to be performed whenever a database page is read into the buffer pool. This is useful to catch cases where pages are being corrupted in memory and then written out to disk with a new page checksum. When they're read back in the checksum will look correct, but the page is corrupt (because of the previous memory corruption). This page auditing goes someway to catching this - especially on non-Enterprise Edition systems that don't have the 'checksum sniffer'.
809 SQL 8 – Limits the amount of Lazy Write activity.
815 Enables latch enforcement. SQL Server 8 (with service pack 4) and SQL Server 9 can perform latch enforcement for data pages found in the buffer pool cache. Latch enforcement changes the virtual memory protection state while database page status changes from "clean" to "dirty" ("dirty" means modified through INSERT, UPDATE or DELETE operation). If an attempt is made to modify a data page while latch enforcement is set, it causes an exception and creates a mini-dump in SQL Server installation's LOG directory. Microsoft support can examine the contents of such mini-dump to determine the cause of the exception. In order to modify the data page the connection must first acquire a modification latch. Once the data modification latch is acquired the page protection is changed to read-write. Once the modification latch is released the page protection changes back to read-only.
818 SQL 8 enables in memory ring buffer used to track last 2048 successful write operations.
830 SQL 9 – disable the reporting of CPU Drift errors in the SQL Server errorlog like SQL Server has encountered 2 occurrence(s) of I/O requests taking longer than 15 seconds to complete
834 Causes SQL Server to use Windows large-page allocations for the memory that is allocated for the buffer pool. The page size varies depending on the hardware platform, but the page size may be from 2 MB to 16 MB. Large pages are allocated at startup and are kept throughout the lifetime of the process. Trace flag 834 improves performance by increasing the efficiency of the translation look-aside buffer (TLB) in the CPU.
Flag 834 applies only to 64-bit versions of SQL Server. You must have the Lock pages in memory user right to turn on trace flag 834. You can turn on trace flag 834 only at startup.
Trace flag 834 may prevent the server from starting if memory is fragmented and if large pages cannot be allocated. Therefore, trace flag 834 is best suited for servers that are dedicated to SQL Server.
For more information about large-page support, http://msdn2.microsoft.com/en-us/library/aa366720.aspx(http://msdn2.microsoft.com/en-us/library/aa366720.aspx)
835 SQL 9 & 10. For 64 bit SQL Server. This turns off Lock pages in memory.
836 Causes SQL Server to size the buffer pool at startup based on the value of the max server memory option instead of based on the total physical memory. You can use trace flag 836 to reduce the number of buffer descriptors that are allocated at startup in 32-bit Address Windowing Extensions (AWE) mode.
Trace flag 836 applies only to 32-bit versions of SQL Server that have the AWE allocation enabled. You can turn on trace flag 836 only at startup.
845 SQL 9 & 10. For 64 bit SQL Server. This turns on Lock pages in memory.
1117 Grows all data files at once, else it goes in turns.
1118 Switches allocations in tempDB from 1pg at a time (for first 8 pages) to one extent. There is now a cache of temp tables. When a new temp table is created on a cold system it uses the same mechanism as for SQL 8. When it is dropped though, instead of all the pages being deallocated completely, one IAM page & one data page are left allocated, then the temp table is put into a special cache. Subsequent temp table creations will look in the cache to see if they can just grab a pre-created temp table. If so, this avoids accessing the allocation bitmaps completely. The temp table cache isn't huge (32 tables), but this can still lead to a big drop in latch contention in tempdb. http://www.sqlskills.com/BLOGS/PAUL/post/Misconceptions-around-TF-1118.aspx
1180 Forces allocation to use free pages for text or image data and maintain efficiency of storage. 1197 applies only in the case of SQL 7 – SP3. Helpful in case when DBCC SHRINKFILE and SHRINKDATABASE commands may not work because of sparsely populated text, ntext, or image columns
1197
1200 Prints lock information (the process ID and type of lock requested).
1202 Insert blocked lock requests into syslocks.
1204 Returns resources and types of locks participating in a deadlock and command affected. Scope: global only
1205 More detailed information about the command being executed at the time of a deadlock. This trace flag was documented in SQL Server 7.0 Books Online, but was not documented in SQL Server 8.
1206 Used to complement flag 1204 by displaying other locks held by deadlock parties
1211

Disables lock escalation based on memory pressure, or based on number of locks. The SQL Server Database Engine will not escalate row or page locks to table locks.

Using this trace flag can generate excessive numbers of locks. This can slow the performance of the Database Engine, or cause 1204 errors (unable to allocate lock resource) because of insufficient memory. For more information, see Lock Escalation (Database Engine).

If both trace flag 1211 and 1224 are set, 1211 takes precedence over 1224. However, because trace flag 1211 prevents escalation in every case, even under memory pressure, we recommend that you use 1224. This helps avoid "out-of-locks" errors when many locks are being used. Scope: global or session

1216

SQL 7 - Disables Health reporting. Lock monitor when detects a (worker thread) resource level blocking scenario. If a SPID that owns a lock is currently queued to the scheduler, because all the assigned worker threads have been created and all the assigned worker threads are in an un-resolvable wait state, the following error message is written to the SQL Server error log:

Error 1223: Process ID %d:%d cannot acquire lock "%s" on resource %s because a potential deadlock exists on Scheduler %d for the resource. Process ID %d:% d holds a lock "%h" on this resource.

1222 Returns the resources and types of locks that are participating in a deadlock and also the current command affected, in an XML format that does not comply with any XSD schema. Scope: global only
1224

Disables lock escalation based on the number of locks. However, memory pressure can still activate lock escalation. The Database Engine escalates row or page locks to table (or partition) locks if the amount of memory used by lock objects exceeds one of the following conditions:

·   40% of the memory that is used by Db Engine, exclusive of memory allocation using Address Windowing Extension (AWE). This is applicable when the locks parameter of sp_configure is set to 0.

·   Forty percent of the lock memory that is configured by using the locks parameter of sp_configure.

If both trace flag 1211 and 1224 are set, 1211 takes precedence over 1224. However, because trace flag 1211 prevents escalation in every case, even under memory pressure, we recommend that you use 1224. This helps avoid "out-of-locks" errors when many locks are being used.

Note:Lock escalation to the table- or HoBT-level granularity can also be controlled by using the LOCK_ESCALATION option of the ALTER TABLE statement.  Scope:global or session

1261

SQL 8 - Disables Health reporting. Lock monitor when detects a (worker thread) resource level blocking scenario. If a SPID that owns a lock is currently queued to the scheduler, because all the assigned worker threads have been created and all the assigned worker threads are in an un-resolvable wait state, the following error message is written to the SQL Server error log:

Error 1229: Process ID %d:%d owns resources that are blocking processes on scheduler %d.

1400 Enables the creation of the database mirroring endpoint, which is required for setting up and using database mirroring. This trace flag is allowed only when using the –T.
1462 Turns off log stream compression and effectively reverts the behavior back to ver 9.
1603 Use standard disk I/O (i.e. turn off asynchronous I/O).
1609 Turns on the unpacking and checking of remote procedure call (RPC) information in Open Data Services. Used only when applications depend on the old behavior.
1610 Boot the SQL dataserver with TCP_NODELAY enabled.
1611 If possible, pin shared memory -- check errorlog for success/failure.
1704 Prints information when a temporary table is created or dropped.
1717 Causes new objects being created to be system objects.
1806 Disables instant file initialization.
1807 Allows creating a database file on a mapped or UNC network location. unsupported under SQL Server 7 & 8.
2301 Enables advanced optimizations that are specific to decision support queries. This option applies to decision support processing of large data sets.
2330 Stops the collection of statistics for sys.db_index_usage_stats.
2382 Statistics collected for system tables.
2389 SQL 9 – Tracks the nature of columns by subsequent statistics updates. When SQL Server determines that the statistics increase three times, the column is branded ascending. The statistics will be updated automatically at query compile.
2390 Does the same like 2389 even if ascending nature of the column is not known and -- never enable without 2389.
2440 Parallel query execution strategy on partitioned tables. SQL 9 – uses a single thread per partition parallel query execution strategy. In ver. 10, multiple threads can be allocated to a single partition, thus improving the query’s response time.
2505 Prevents DBCC TRACEON 208, SPID 10 errors from appearing in the error log.
2508 Disables parallel non-clustered index checking for DBCC CHECKTABLE.
2509 Used with DBCC CHECKTABLE.html to see the total count of ghost records in a table
2520 Force DBCC HELP to return syntax of undocumented DBCC statements. If 2520 is not turned on, DBCC HELP will refuse to give you the syntax stating: "No help available for DBCC statement 'undocumented statement'".
2528

Disables parallel checking of objects by DBCC CHECKDB, CHECKFILEGROUP and CHECKTABLE. By default, the degree of parallelism is automatically determined by the query processor. The maximum degree of parallelism is configured just like that of parallel queries. For more information, see max degree of parallelism Option.

Parallel DBCC should typically be left enabled. For DBCC CHECKDB, the query processor reevaluates and automatically adjusts parallelism with each table or batch of tables checked. Sometimes, checking may start when the server is almost idle. An administrator who knows that the load will increase before checking is complete may want to manually decrease or disable parallelism.

Disabling parallel checking of DBCC can cause it to take much longer to complete and if DBCC is run with the TABLOCK feature enabled and parallelism set off, tables may be locked for longer periods of time.

Scope: global or session

2537 SQL 9 & 10. Allows function ::fn_dblog to look inside all logs (not just the active log).
2542 SQL 8 – Used with Sqldumper.exe to get certain dumps. In range 254x – 255x.
2551 Adds additional information to the dump file.
2701 Sets the @@ERROR system function to 50000 for RAISERROR messages with severity levels of 10 or less. When disabled, sets the @@ERROR system function to 0 for RAISERROR messages with severity levels of 10 or less.
2861 Cache query plans for queries that have a cost of zero or near to zero.
3001 Stops sending backup entries into MSDB.
3004 Gives out more detailed information about restore & backup activities.
3031 SQL 9 - will turn the NO_LOG and TRUNCATE_ONLY options into checkpoints in all recovery modes.
3104 Causes SQL Server to bypass checking for free space.
3111 Cause LogMgr::ValidateBackedupBlock to be skipped during backup and restore operations.
3205 If a tape drive supports hardware compression, either the DUMP or BACKUP statement uses it. With this trace flag, you can disable hardware compression for tape drivers. This is useful when you want to exchange tapes with other sites or tape drives that do not support compression. Scope: global or session
3213 Trace SQL Server activity during backup process so that we will come to know which part of backup process is taking more time.
3222 Disables the read ahead that is used by the recovery operation during roll forward operations.
3226 With this trace flag, you can suppress BACKUP COMPLETED log entries going to WIN and SQL logs.
3231 SQL 8 & 9 - will turn the NO_LOG and TRUNCATE_ONLY options into no-ops in FULL/BULK_LOGGED recovery mode, and will clear the log in SIMPLE recovery mode.
3282 SQL 6.5 – Used after backup restoration fails refer to microsoft for article Q215458.
3422 Cause auditing of transaction log records as they're read (during transaction rollback or log recovery). This is useful because there is no equivalent to page checksums for transaction log records and so no way to detect whether log records are being corrupted e careful with these trace flags - I don't recommend using them unless you are experiencing corruptions that you can't diagnose. Turning them on will cause a big CPU hit because of the extra auditing that's happening.
3502 Tracks CHECKPOINT - Prints a message to the log at the start and end of each checkpoint.
3503 Indicates whether the checkpoint at the end of automatic recovery was skipped for a database (this applies only to read-only databases).
3504 For internal testing. Will raise a bogus log-out-of-space condition from checkpoint()
3505 Disables automatic checkpoints. May increase recovery time and can prevent log space reuse until the next checkpoint is issued. Make sure to issue manual checkpoints on all read/write databases at appropriate time intervals.
Note does not prevent the internal checkpoints that are issued by certain commands, such as BACKUP.
3601 Stack trace when error raised. Also see 3603
3602 Records all error and warning messages sent to the client.
3603 SQL Server fails to install on tricore, Bypass SMT check is enabled, flags are added via registry. Also see 3601.
3604 Sends trace output to the client. This trace flag is used only when setting trace flags with DBCC TRACEON and DBCC TRACEOFF.
3605 Sends trace output to the error log.  (if SQL Server is started from CMD output also appears on the screen)
3607 Trace flag 3607 skips the recovery of databases on the startup of SQL Server and clears the TempDB. Setting this flag lets you get past certain crashes, but there is a chance that some data will be lost
3608 Prevents SQL Server from automatically starting and recovering any database except the master database. Databases will be started and recovered when accessed. Some features, such as snapshot isolation and read committed snapshot, might not work.
3609 Skips the creation of the tempdb database at startup. Use this trace flag if the device or devices on which tempdb resides are problematic or problems exist in the model database.
3610 SQL 9. Divide by zero to result in NULL instead of error.
3625 Limits the amount of information returned in error messages. For more information, see Metadata Visibility Configuration. Scope: global only
3626 Turns on tracking of the CPU data for the sysprocesses table.
3640 Eliminates the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. This is similar to the session setting of SET NOCOUNT ON, but when set as a trace flag, every client session is handled this way.
3689 Logs extended errors to errorlog when network disconnect occurs, turned off by default. Will dump out the socket error code this can sometimes give you a clue as to the root cause.
3913 SQL 7/8 – SQL Server does not update the rowcnt column of the sysindexes system table until the transaction is committed. When turned on the optimizer gets row count information from in-memory metadata that is saved to sysindexes system table when the transaction commits.
4013

This trace flag writes an entry to the SQL Server error log when a new connection is established. For each connection that occurs, the trace flag writes two entries that look like this:

Login: sa saSQL Query Analyzer(local)ODBCmaster, server process ID (SPID): 57, kernel process ID (KPID): 57.
Login: sa XANADUsaSQL Query Analyzer(local)ODBCmaster, server process ID (SPID): 57, kernel process ID (KPID): 57.

4022 If turns on, then automatically started procedures will be bypassed.
4029 Logs extended errors to errorlog when network disconnect occurs, turned off by default. Will dump out the socket error code this can sometimes give you a clue as to the root cause.
4030 Prints both a byte and ASCII representation of the receive buffer. Used when you want to see what queries a client is sending to SQL Server. You can use this trace flag if you experience a protection violation and want to determine which statement caused it. Typically, you can set this flag globally or use SQL Server Enterprise Manager. You can also use DBCC INPUTBUFFER.
4031 Prints both a byte and ASCII representation of the send buffers (what SQL Server sends back to the client). You can also use DBCC OUTPUTBUFFER.
4032 Traces the SQL commands coming in from the client. The output destination of the trace flag is controlled with the 3605/3604 trace flags.
4101

SQL 9 - Query that involves an outer join operation runs very slowly. However, if you use the FORCE ORDER query hint in the query, the query runs much faster. Additionally, the execution plan of the query contains the following text in theWarnings column:  NO JOIN PREDICATE

Turn these trace flags after HOTFIX is applied (SP2 CUP4)

4121
4606 Over comes SA password by startup. Refer to Ms article 936892.
4612 Disable the ring buffer logging - no new entries will be made into the ring buffer.
4613 Generate a minidump file whenever an entry is logged into the ring buffer.
4616 Makes server-level metadata visible to application roles. In SQL Server, an application role cannot access metadata outside its own database because application roles are not associated with a server-level principal. This is a change of behavior from earlier versions of SQL Server. Setting this global flag disables the new restrictions, and allows for application roles to access server-level metadata. Scope: global only
5302 Alters default behavior of select…INTO (and other processes) that lock system tables for the duration of the transaction. This trace flag disables such locking during an implicit transaction. 
6527

Disables generation of a memory dump on the first occurrence of an out-of-memory exception in CLR integration. By default, SQL Server generates a small memory dump on the first occurrence of an out-of-memory exception in the CLR. The behavior of the trace flag is as follows:

·   If this is used as a startup trace flag, a memory dump is never generated. However, a memory dump may be generated if other trace flags are used.

·   If this trace flag is enabled on a running server, a memory dump will not be automatically generated from that point on. However, if a memory dump has already been generated due to an out-of-memory exception in the CLR, this trace flag will have no effect. Scope: global only

7103 Disable table lock promotion for text columns. Refer to Ms article - 230044
7300 Retrieves extended information about any error you encounter when you execute a distributed query.
7501 Dynamic cursors are used by default on forward-only cursors. Dynamic cursors are faster than in earlier versions and no longer require unique indexes. This flag disables the dynamic cursor enhancements and reverts to version 6.0 behavior.
7502 Disables the caching of cursor plans for extended stored procedures.
7505 Enables version 6.x handling of return codes when calling dbcursorfetchex and the resulting cursor position follows the end of the cursor result set.
7525 Reverts to the SQL Server 7 behavior of closing nonstatic cursors regardless of the SET CURSOR_CLOSE_ON_COMMIT state in SQL Server 8.
7601 Turns on full text indexing. Together these four gather more information about full text search (indexing process) to the error log.
7603
7604
7605
7646 SQL 10. Avoids blocking when using full text indexing. An issue we experienced that full text can be slow when there is a high number of updates to the index and is caused by blocking on the docidfilter internal table.
7806 Enables a dedicated administrator connection (DAC) on SQL Svr Express. By default, no DAC resources are reserved on SQL Server Express.
8004 SQL server to create a mini dump once you enable 2551 and a out of memory condition is hit.
8011 Disables the collection of additional diagnostic information for Resource Monitor. You can use the information in this ring buffer to diagnose out-of-memory conditions. Scope: GLOBAL.
8012

Records an event in the schedule ring buffer every time that one of the following events occurs:

·   A scheduler switches context to another worker.

·   A worker is suspended or resumed.

·   A worker enters the preemptive mode or the non-preemptive mode.

You can use the diagnostic information in this ring buffer to analyze scheduling problems. For example, you can use the information in this ring buffer to troubleshoot problems when SQL Server stops responding.
Trace flag 8012 disables recording of events for schedulers. You can turn on trace flag 8012 only at startup.

8018 Disables the creation of the ring buffer, and no exception information is recorded. The exception ring buffer records the last 256 exceptions that are raised on a node. Each record contains some information about the error and contains a stack trace. A record is added to the ring buffer when an exception is raised.
8019 Disables stack collection during the record creation, has no effect if trace flag 8018 is turned on. Disabling the exception ring buffer makes it more difficult to diagnose problems that are related to internal server errors. You can turn on trace flag 8018 and trace flag 8019 only at startup.
8020 SQL Server uses the size of the working set when SQL Server interprets the global memory state signals from the operating system. Trace flag 8020 removes the size of the working set from consideration when SQL Server interprets the global memory state signals. If you use this trace flag incorrectly, heavy paging occurs, and the performance is poor. Therefore, contact Microsoft Support before you use. You can turn on trace flag 8020 only at startup
8033 SQL 9 – disable the reporting of CPU Drift errors in the SQL Server errorlog like time stamp counter of CPU on scheduler id 1 is not synchronized with other CPUs.
8202 Used to replicate UPDATE as DELETE/INSERT pair at the publisher. i.e. UPDATE commands at the publisher can be run as an "on-page DELETE/INSERT" or a "full DELETE/INSERT". If the UPDATE command is run as an "on-page DELETE/INSERT," the Logreader send UDPATE command to the subscriber, If the UPDATE command is run as a "full DELETE/INSERT," the Logreader send UPDATE as DELETE/INSERT Pair. If you turn on trace flag 8202, then UPDATE commands at the publisher will be always send to the subscriber as DELETE/INSERT pair.
8206 Supports stored procedure execution with a user specified owner name for SQL Server subscribers or without owner qualification for heterogeneous subscribers in SQL Server 8.
8207 Enables singleton updates for Transactional Replication, released with SQL Server 8 SP 1.
8501 Writes detailed information about Ms-DTC context & state changes to the log.
8599 Allows you to use a savepoint within a distributed transaction.
8602 Ignore index hints that are specified in query/procedure.
8679 Prevents the SQL Server optimizer from using a Hash Match Team operator.
8687 Used to disable query parallelism.
8721 Dumps information into the error log when AutoStat has been run.
8722 Disable all other types of hints. This includes the OPTION clause.
8744 Disables pre-fetching for the Nested Loops operator. Incorrect use of this trace flag may cause additional physical reads when SQL Server executes plans that contain the Nested Loops operator. For more information about the Nested Loops operator, see the "Logical and physical operators reference" topic in SQL Server 9 BOL.
You can turn on trace flag 8744 at startup or in a user session. When you turn on trace flag 8744 at startup, the trace flag has global scope. When you turn on trace flag 8744 in a user session, the trace flag has session scope.
8755 Disable any locking hints like READONLY. By setting this, you allow SQL Server to dynamically select the best locking hint for the query.
8783 Allows DELETE, INSERT, and UPDATE statements to honor the SET ROWCOUNT ON setting when enabled.
8816 Logs every two-digit year conversion to a four-digit year.
9134 SQL 8 – Does additional reads to test if the page is allocated & linked correctly this checks IAM & PFS. Fixes error 601 for queries under Isolation level read uncommitted.
9268

SQL 8 – When SQL Server runs a parameterized query that contains several IN clauses, each with a large number of values, SQL Server may return the following error message after a minute or more of high CPU utilization:

Server: Msg 8623, Level 16, State 1
Internal Query Processor Error: The query processor could not produce a query plan. Contact your primary support provider for more information.

http://support.microsoft.com/kb/325658 Enabling this trace flag activates the hotfix.

'Trace Flag' 카테고리의 다른 글

최소로그 Flag -T610  (0) 2011.10.13
Trace Flag  (0) 2010.06.04
Admin::TF 1118 사용 이유  (0) 2009.11.04
2010. 6. 7. 23:51

dm_os_performance_counters , Server/Process Information

SQL SERVER 2005 이상


출처: http://www.sqlservercentral.com/scripts/Monitoring/68069/

This script displays data from the dynamic management view called: sys.dm_os_performance and presents it in a report. I recommend that you look closer to this view for all your statistical needs.

If you find other information that you want to include, just modify this script to reflect the additional information.

Hope you find this script useful.

--			                     SQL Doctor 
--    			 								
--			           Welcome to the World of Databases
--
--			                   By Rudy Panigas 
--
-- Code Name: usp_dba_SQL_Server_Stats  
-- Date of Creation: Aug 27, 2009 - version 1.0
-- Updated: Sept 3, 2009 - version 2.1   
-- Comments: Code will produce a report with important information about your SQL server (2005/2008) and its processes
--

USE [master] -- Doesn't have to be in master database. 
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_dba_SQL_Server_Stats]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_dba_SQL_Server_Stats]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[usp_dba_SQL_Server_Stats]
AS

PRINT ' SQL 2005/2008 Server Statistics'
PRINT ' -------------------------------'
PRINT ''
PRINT ' Displaying statistics of SQL server '
PRINT ' '
PRINT '...Buffer Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE 

   ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Buffer cache hit ratio')
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Buffer cache hit ratio base')
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Page lookups/sec')
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Free pages')
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Total pages')
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Readahead pages/sec') 
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Page reads/sec')      
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Page writes/sec')     
OR ([object_name] LIKE '%Buffer Manager%'and [counter_name] = 'Page life expectancy')


PRINT '...Memory Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE 
   ([object_name] LIKE '%memory manager%'and [counter_name] = 'Connection Memory (KB)')       
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Granted Workspace Memory (KB)')
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Lock Memory (KB)')             
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Lock Blocks Allocated')        
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Lock Owner Blocks Allocated')  
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Lock Blocks')                  
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Lock Owner Blocks')            
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Maximum Workspace Memory (KB)')
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Memory Grants Outstanding')    
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Memory Grants Pending')        
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Optimizer Memory (KB)')        
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'SQL Cache Memory (KB)')        
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Target Server Memory (KB)')    
OR ([object_name] LIKE '%memory manager%'and [counter_name] = 'Total Server Memory (KB)')     


PRINT '...General Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE
   ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Active Temp Tables')                  	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Temp Tables Creation Rate')
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Logins/sec')                          	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Logouts/sec')                         	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'User Connections')                    	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Logical Connections')                 	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Transactions')                        	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Mars Deadlocks')                      	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'HTTP Authenticated Requests')
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Processes blocked')                   	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Temp Tables For Destruction')         	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Event Notifications Delayed Drop')    	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'Trace Event Notification Queue')      	
OR ([object_name] LIKE '%General Statistics%'and [counter_name] = 'SQL Trace IO Provider Lock Waits')    	
			

PRINT '...Locks Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE

   ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Timeouts/sec')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Number of Deadlocks/sec')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Waits/sec')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Wait Time (ms)')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Average Wait Time (ms)')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Average Wait Time Base')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Timeouts (timeout > 0)/sec')

PRINT '...Total for Locks Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE

   ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Requests/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Timeouts/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Number of Deadlocks/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Waits/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Wait Time (ms)' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Average Wait Time (ms)' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Average Wait Time Base' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Locks%'and [counter_name] = 'Lock Timeouts (timeout > 0)/sec' and [instance_name] ='_Total')
			

PRINT '...Temp DB Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE

   ([object_name] LIKE '%Databases%'and [counter_name] = 'Data File(s) Size (KB)' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log File(s) Size (KB)' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log File(s) Used Size (KB)' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Percent Log Used' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Active Transactions' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Transactions/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Repl. Pending Xacts' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Repl. Trans. Rate' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Cache Reads/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Cache Hit Ratio' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Cache Hit Ratio Base' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Bulk Copy Rows/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Bulk Copy Throughput/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Backup/Restore Throughput/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'DBCC Logical Scan Bytes/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Shrink Data Movement Bytes/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Flushes/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Bytes Flushed/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Flush Waits/sec' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Flush Wait Time' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Truncations' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Growths' and [instance_name] ='tempdb')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Shrinks' and [instance_name] ='tempdb')
																	


PRINT '...Totals of Database Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE

   ([object_name] LIKE '%Databases%'and [counter_name] = 'Data File(s) Size (KB)' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log File(s) Size (KB)' and [instance_name] ='_Total')          
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log File(s) Used Size (KB)' and [instance_name] ='_Total')     
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Percent Log Used' and [instance_name] ='_Total')               
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Active Transactions' and [instance_name] ='_Total')            
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Transactions/sec' and [instance_name] ='_Total')               
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Repl. Pending Xacts' and [instance_name] ='_Total')            
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Repl. Trans. Rate' and [instance_name] ='_Total')              
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Cache Reads/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Cache Hit Ratio' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Cache Hit Ratio Base' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Bulk Copy Rows/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Bulk Copy Throughput/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Backup/Restore Throughput/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'DBCC Logical Scan Bytes/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Shrink Data Movement Bytes/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Flushes/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Bytes Flushed/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Flush Waits/sec' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Flush Wait Time' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Truncations' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Growths' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Databases%'and [counter_name] = 'Log Shrinks' and [instance_name] ='_Total')



PRINT '...SQL Error Statistics'
PRINT ' '
SELECT 
  [instance_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE

   ([object_name] LIKE '%SQL Errors%'and [counter_name] = 'Errors/sec')
OR ([object_name] LIKE '%SQL Errors%'and [counter_name] = 'Errors/sec')
OR ([object_name] LIKE '%SQL Errors%'and [counter_name] = 'Errors/sec')
OR ([object_name] LIKE '%SQL Errors%'and [counter_name] = 'Errors/sec')
OR ([object_name] LIKE '%SQL Errors%'and [counter_name] = 'Errors/sec')



PRINT '...SQL Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE
   ([object_name] LIKE '%SQL Statistics%'and [counter_name] = 'SQL Compilations/sec')
OR ([object_name] LIKE '%SQL Statistics%'and [counter_name] = 'SQL Re-Compilations/sec')



PRINT '...Plan Cache Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE
   ([object_name] LIKE '%Plan Cache%'and [counter_name] = 'Cache Hit Ratio' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Plan Cache%'and [counter_name] = 'Cache Hit Ratio Base' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Plan Cache%'and [counter_name] = 'Cache Pages' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Plan Cache%'and [counter_name] = 'Cache Object Counts' and [instance_name] ='_Total')
OR ([object_name] LIKE '%Plan Cache%'and [counter_name] = 'Cache Objects in use' and [instance_name] ='_Total')


PRINT '...Transactions Statistics'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE ([object_name] LIKE '%Transactions%')


PRINT '...Wait Statistics. Average execution time (ms)'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE ([object_name] LIKE '%Wait Statistics%'and [instance_name] = 'Average execution time (ms)')                          

--
PRINT '...Wait Statistics. Waits in progress'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE ([object_name] LIKE '%Wait Statistics%'and [instance_name] = 'Waits in progress')    

--
PRINT '...SQL Execution Statistics. Average execution time (ms)'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE
   ([object_name] LIKE '%Exec Statistics%'and [counter_name] = 'Extended Procedures')  
OR ([object_name] LIKE '%Exec Statistics%'and [counter_name] = 'DTC calls')            
OR ([object_name] LIKE '%Exec Statistics%'and [counter_name] = 'OLEDB calls')          
OR ([object_name] LIKE '%Exec Statistics%'and [counter_name] = 'Distributed Query')    
																				
--
PRINT '...SQL Execution Statistics. Execution in progress'
PRINT ' '
SELECT 
[counter_name] AS 'Description'
, [cntr_value] AS 'Current Value'
 from sys.dm_os_performance_counters 
WHERE ([object_name] LIKE '%Exec Statistics' and [instance_name] ='Execs in progress')
GO


2010. 6. 7. 23:43

SQL2008에서 SQL2000 DTS열기

SQL Server 2008에서는 DTS 패키지에 대한 디자인 타임 지원을 설치하지 않습니다. SQL Server 2008 도구를 사용하여 DTS 패키지를 열어서 보려면 다음 절차에 설명된 대로 이러한 디자인 타임 지원을 다운로드하고 설치해야 합니다.
참고:
다운로드할 수 있는 DTS 패키지 디자이너는 SQL Server 2008 도구를 사용하지만 디자이너의 기능은 SQL Server 2008용으로 업데이트되지 않았습니다.

데이터 변환 서비스 패키지를 위한 디자인 타임 지원을 설치하려면 ·

         인터넷 브라우저에서 Microsoft SQL Server 2005용 기능 팩 페이지를 열고 Microsoft SQL Server 2000 DTS 디자이너 구성 요소를 다운로드하여 설치합니다.
기본적으로 32비트 컴퓨터에서 SQL Server 2000의 이진 파일은 %ProgramFiles%\Microsoft SQL Server\80\Tools\Binn 폴더에 있으며, SQL Server 2008의 이진 파일은 %ProgramFiles%\Microsoft SQL Server\100\Tools\Binn 폴더에 있습니다. 이러한 기본 위치를 사용하면 PATH 환경 변수에서 SQL Server 2000 이진 파일의 경로가 SQL Server 2008 이진 파일의 경로 앞에 올 수 있습니다. 이러한 경우 DTS 디자이너를 사용하려고 하면 오류 메시지가 표시될 수 있습니다. 이러한 오류를 해결하려면 다음 절차에 설명된 대로 디자이너에 필요한 파일을 새로운 위치로 복사합니다.
참고:
64비트 컴퓨터의 경우 다음 절차에서 %ProgramFiles%를 %ProgramFiles(x86)%로 대체하십시오.

SQL Server Management Studio에서 DTS 디자이너를 사용할 수 있도록 하려면

1.       %ProgramFiles%\Microsoft SQL Server\80\Tools\Binn 폴더에 있는 SEMSFC.DLL, SQLGUI.DLL 및 SQLSVC.DLL 파일을 %ProgramFiles%\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE 폴더로 복사합니다.
2.       %ProgramFiles%\Microsoft SQL Server\80\Tools\Binn\Resources 폴더에 있는 SEMSFC.RLL, SQLGUI.RLL 및 SQLSVC.RLL 파일을 %ProgramFiles%\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Resources\%lang_id% 폴더로 복사합니다. 예를 들어 미국 영어이면 lang_id 하위 폴더는 "1033"입니다.



Business Intelligence Development Studio에서 DTS 디자이너를 사용할 수 있도록 하려면

1.       %ProgramFiles%\Microsoft SQL Server\80\Tools\Binn 폴더에 있는 SEMSFC.DLL, SQLGUI.DLL 및 SQLSVC.DLL 파일을 %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE 폴더로 복사합니다.
2.       %ProgramFiles%\Microsoft SQL Server\80\Tools\Binn\Resources 폴더에 있는 SEMSFC.RLL, SQLGUI.RLL 및 SQLSVC.RLL 파일을 the %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\Resources\%lang_id% 폴더로 복사합니다. 예를 들어 미국 영어이면 lang_id 하위 폴더는 "1033"입니다


 


1. SQLServer2005_DTS.msi 설치

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11988


2.  파일 복사

  FROM : C:\Program Files\Microsoft SQL Server\80\Tools\Binn

   TO : C:\Program Files\Microsoft SQL Server\100\Tools\Binn

3. SSMS 재 시작



.

'Business Inteligence (SSIS)' 카테고리의 다른 글

SSIS 데이터 이관 속도  (0) 2012.08.09
SSIS::플랫 파일 가져오기 에러.  (0) 2012.02.09
For컨테이너-무한루프  (0) 2010.06.03
스크립트task사용  (0) 2010.06.03
2010. 6. 4. 01:20

SQL 2008 -New DataType-Date

 January 2, 2008
New datetime datatypes in SQL Server 2008

By Muthusamy Anantha Kumar aka The MAK

 

SQL Server 2008


From the beginning, Microsoft SQL Server DBAs have longed for two different datatypes, where you could store time and date separately. The long wait is over. In all of the older versions, we had only one data type that could store Datetime datatype, and it stored both the value of the date and the value of the time.

Finally, in Microsoft SQL Server 2008, Microsoft is introducing a set of new datatypes for storing date, time and both date and time together. The new data types store more data as well, which means you can store dates anywhere from 01-01-01 to 9999-12-31 and also store time up to the fraction of 9999999.

This article illustrates the usage and functionality of different datatypes in Microsoft SQL Server 2008, namely date, time, datetime, datetime2 and datetimeoffset datatypes.

Note: This article is written based on the Microsoft SQL Server 2008 – Nov CTP

TIME

The datatype TIME is primarily used for storing the time of a day. This includes Hours, minutes, Seconds etc. It is based on a 24-hour clock. The datatype TIME can store seconds up to the fraction of 9999999.

Let us declare a variable with the datatype TIME and store some data.

declare @mytime TIME
set @mytime = GETDATE()
select MyTime = @mytime

The result is shown below. [Refer Fig 1.0]

MyTime
01:48:18.4870000


Fig 1.0

When you declare a variable with datatype TIME with no precision, SQL Server assumes a 7 digit precision as shown above.

The time range is from 00:00:00 through 23:59:59.9999999.

We could limit the precision of the datatype as shown below.

declare @mytime TIME(3)
set @mytime = GETDATE()
select MyTime = @mytime 

The result is shown below. [Refer Fig 1.2]

Result

MyTime
01:51:25.580


Fig 1.1

DATE

The datatype DATE is used for storing the date only. This includes Month, Day and year.

The value of date can be anywhere from 01-01-01 to 9999-12-31.

Let’s declare a variable with the datatype DATE and store some data.

declare @mydate DATE
set @mydate = GETDATE()
Select Mydate = @MyDate
set @mydate = '01/01/1997'
Select Mydate = @MyDate
set @mydate = '01/31/9999'
Select Mydate = @MyDate
set @mydate = '01/01/0001'
Select Mydate = @MyDate

The range for date is from 0001-01-01 through 9999-12-31

The result is shown below. [Refer Fig 1.2]

Result

MyDate
2007-12-18
 
MyDate
1997-01-01
 
MyDate
9999-01-31
 
MyDate
0001-01-01


Fig 1.2

DATETIME2

The data type DATETIME2 is the combination of the datatype DATE and TIME. DATETIME2 is used to store both a date value ranging from 01-01-01 to 9999-12-31 as well as a time value up to the fraction of 9999999.

Let’s declare a variable with the datatype DATETIME2 and store some data as shown below.

declare @mydate DATETIME2
set @mydate = GETDATE()
Select Mydate = @MyDate
set @mydate = convert(datetime2,'01/01/1997 16:14:00.1234567')
Select Mydate = @MyDate
set @mydate = convert(datetime2,'01/01/0001 16:14:00.1234567')
Select Mydate = @MyDate
The range for DATETIME2 is from 0001-01-01 00:00:00.0000000 through 9999-12-31 23:59:59.9999999

The result is shown below. [Refer Fig 1.3]

Result

MyDate
2007-12-18 02:11:45.3130000
 
MyDate
1997-01-01 16:14:00.1234567
 
MyDate
0001-01-01 16:14:00.1234567


Fig 1.3

We could limit the precision as shown below.

Declare @mydate DATETIME2(4)
set @mydate = GETDATE()
Select Mydate = @MyDate
set @mydate = convert(datetime2(4),'01/01/1997 16:14:00.1234567')
Select Mydate = @MyDate

The result is shown below. [Refer Fig 1.2]

Result

MyDate
2007-12-18 02:14:54.8130
 
MyDate
1997-01-01 16:14:00.1235

SMALLDATETIME and DATETIME

Microsoft SQL Server 2008 continues to support existing data types such as datetime and smalldatetime.

The range for the datatype smalldatetime is from 1900-01-01 through 2079-06-06. Execute the following query as shown.

Declare @Mydate datetime
Set @MyDate = getdate()
Select MyDate = @MyDate

The result is shown below. [Refer Fig 1.4]

Result

MyDate
2007-12-18 02:31:35.347


Fig 1.4

The range for the datatype datetime is from 1753-01-01 through 9999-12-31.

Execute the following query as shown.

Declare @Mydate smalldatetime
Set @MyDate = getdate()
Select MyDate = @MyDate

The result is shown below. [Refer Fig 1.5]

Result

MyDate
2007-12-18 02:34:00.000


Fig 1.5

DATETIMEOFFSET

Microsoft SQL Server 2008 introduces a new datetime datatype called datetimeoffset. Datetimeoffset actually defines the date with the combination of the time of a day that is timezone aware. In addition, the clock is a 24-hour cycle.

The timezone offset range is from -14:00 through +14:00

Execute the query below to get the timeoffset.

Select 
CAST('2007-05-08 12:35:29.1234567 +12:15' AS datetimeoffset(7)) AS 'datetimeoffset'

The result is shown below. [Refer Fig 1.6]

Result

datetimeoffset
2007-05-08 12:35:29.1234567 +12:15


Fig 1.6

You can use the convert and cast functions to convert to and from different datetime datatypes.

Example:

Declare @mydate DATETIME2(4)
set @mydate = GETDATE()
select @mydate as OriginalDate
select CONVERT (smalldatetime,@mydate ) as Smalldate
select CONVERT (time,@mydate ) as Justtime

Result

OriginalDate
2007-12-19 02:15:09.3130
 
Smalldate
2007-12-19 02:15:00.000
 
Justtime
02:15:09.3130000

Note: This article is written based on the Microsoft SQL Server 2008 – Nov CTP.

Conclusion

This article has illustrated the usage and function of the various datatypes related to Date and time, namely date, time, datetime, datetime2 and datetimeoffset.

이 글은 스프링노트에서 작성되었습니다.


'Common Admin' 카테고리의 다른 글

MCITP 취득 방법  (0) 2010.10.06
RML Utilities for SQL Server  (0) 2010.08.23
SQLDMO  (0) 2010.06.04
SQL Server의 Procedure Cache 사이즈  (0) 2010.06.04
2010. 6. 4. 01:20

BACKUP compression

SQL 2008

 December 19, 2007
BACKUP compression in SQL Server 2008

By Muthusamy Anantha Kumar aka The MAK

After a long wait, SQL Server 2008 is going to be released with inbuilt compression for backups. Until the release of SQL Server 2005, compression was only available via third party backup software such as  SQL LiteSpeed, SQLZip, etc.

This article demonstrates how to take Full, Differential and Transactional log backups with compression, without compression and how to enable compression as a default.

Note: This article is written based on the SQL Server 2008 – Nov CTP.

Let us create a database “MyDB” as shown below.

USE [master]
GO
 
/****** Object:  Database [MyDB]    
        Script Date: 12/10/2007 01:08:14 ******/
IF  EXISTS (SELECT name FROM sys.databases WHERE name = N'MyDB')
DROP DATABASE [MyDB]
GO
 
USE [master]
GO
/****** Object:  Database [MyDB]    
        Script Date: 12/10/2007 01:05:09 ******/
CREATE DATABASE [MyDB] ON  PRIMARY 
( NAME = N'MyDB_Data', 
  FILENAME = 
  N'F:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\
        MSSQL\DATA\MyDB_Data.mdf' , 
  SIZE = 2176KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'MyDB_log', 
  FILENAME = 
  N'F:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\
        MSSQL\DATA\MyDB_log.LDF' , 
  SIZE = 504KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [MyDB] SET RECOVERY FULL 
GO

Now let us create a table “MyTable” in the database “MyDB” as shown below

USE [MyDB]
GO
 
/****** Object:  Table [dbo].[MyTable]    
        Script Date: 12/10/2007 01:12:00 ******/
IF  EXISTS (SELECT * FROM sys.objects 
        WHERE object_id = OBJECT_ID(N'[dbo].[MyTable]') 
        AND type in (N'U'))
DROP TABLE [dbo].[MyTable]
GO
USE [MyDB]
GO
 
/****** Object:  Table [dbo].[MyTable]    
        Script Date: 12/10/2007 01:12:26 ******/
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
SET ANSI_PADDING ON
GO
 
CREATE TABLE [dbo].[MyTable](
          [id] [int] NULL,
          [name] [char](100) NULL
) ON [PRIMARY]
 
GO
 
SET ANSI_PADDING OFF
GO

Let’s add 10000 rows of data to the table “MyTable” as shown below.

USE [MyDB]
GO
 
declare @myid int
set @myid=1
while @myid<=10000
begin
insert into MyTable select @myid, 'A'+convert(varchar(10),@myid)
set @myid =@myid +1
end

Select the data using the following T-SQL command. [Refer Fig 1.0]

use MyDB
go
Select * from MyTable
go


Fig 1.0

Create a folder, D:\Backup, as shown below. [Refer Fig 1.1]


Fig 1.1

Now let us take a full backup as shown below. [Refer Fig 1.2]

Backup Database MyDB to disk ='d:\Backup\MyDB_Full.bak' with init


Fig 1.2

Let’s add some more data [1000 rows] to the table “MyTable” in the database “MyDB” as shown below.

USE [MyDB]
GO
 
declare @myid int
set @myid=1
while @myid<=1000
begin
insert into MyTable select @myid, 'A'+convert(varchar(10),@myid)
set @myid =@myid +1
end

Now let us a take a transaction log backup, as shown below. [Refer Fig 1.3]

Backup log  MyDB to disk ='d:\Backup\MyDB_TLog_1.bak' with init


Fig 1.3

By default, SQL Server does not compress the backups. We can compress the backups in two different ways.

a. Change the default behavior of SQL Server to compress all of the backups.

b. Add an optional keyword “With COMPRESSION” in the backup clause.

The database MyDB and the Full backup, Transactional log backup that we took were without compression. That is the default SQL Server behavior.

Now let’s take a full backup of the database with compression as shown below. [Refer Fig 1.4]

Backup Database MyDB to disk ='d:\Backup\MyDB_Full2.bak' with COMPRESSION


Fig 1.4

From figure 1.4, you can see that the size of MyDB_Full2.bak is much smaller when compared to MyDB_Full.Bak and MyDB_Tlog_1.bak.

Add some more data [1000 rows] to the table “MyTable” in the database “MyDB” as shown below.

USE [MyDB]
GO
 
declare @myid int
set @myid=1
while @myid<=1000
begin
insert into MyTable select @myid, 'A'+convert(varchar(10),@myid)
set @myid =@myid +1
end

Now let’s take a transaction log backup as shown below. [Refer Fig 1.5]

Backup log  MyDB to disk ='d:\Backup\MyDB_TLog_new.bak' with COMPRESSION


Fig 1.5

In figure 1.5, you can see that the size of MyDB_Tlog_new.bak is much smaller when compared to MyDB_Tlog_1.bak.

Let’s take a differential backup without compression and compare it with the differential backup with compression.

Execute the following commands as shown below. [Refer Fig 1.6]

backup database MyDB to disk ='d:\Backup\MyDB_Diff.bak' with differential
 
backup database MyDB to disk ='d:\Backup\MyDB_Diff2.bak' with differential, COMPRESSION


Fig 1.6

Fig 1.6 shows the compression ratio between MyDB_Diff.bak and MyDB_Diff2.bak.

Let’s change the default behavior of SQL Server from uncompressed backup to compressed. This can be done using the SP_CONGIFURE command.

Execute the command as shown below.

USE master
GO
EXEC sp_configure 'backup compression default', '1'
GO
RECONFIGURE WITH OVERRIDE
GO

Now let’s take a full backup of the MyDB database, without the optional keyword “WITH COMPRESSION”. [Refer Fig 1.7]

Backup Database MyDB to disk ='d:\Backup\MyDB_Full3.bak'


Fig 1.7

From figure 1.7, we can clearly see that the backup by default is compressed.

이 글은 스프링노트에서 작성되었습니다.


'Backup/Restory' 카테고리의 다른 글

detach 한 DB를 다른 서버에서 attach 하면 log 백업 바로 가능 한가?  (0) 2013.03.13
Admin::Recovery Model  (0) 2010.06.04
백업성공보고  (0) 2010.06.03
All DB 백업  (0) 2010.06.03
2010. 6. 4. 01:19

저장 프로시저 및 함수의 마법 깨트리기 #1

 

저장 프로시저 및 함수의 마법 깨트리기

Herts Chen

본 자료는 OPENQUERY를 사용하여 UDF 및 SQL 문에서 저장 프로시저를 호출할 수 없는 문제를 극복하는 방법을 다룬 Herts Chen의 세 개의 시리즈 기사 중 첫 번째입니다. 이 자료에서는 OPENQUERY의 한계 중 하나에 대해 다루며 OPENQUERY가 그러한 한계를 극복하도록 하는 방법을 제시합니다.

RDBMS의 장점 중 하나는 기본이 되는 집합 기반 쿼리 언어가 SQL이라는 것입니다. 쿼리는 항상 연속되는 다량의 T-SQL 스크립트에서 실행해야 하는 경우보다는 단일 SQL 문으로 표시할 수 있을 경우 더 간결하고 더 잘 최적화됩니다. 예를 들면 레코드가 50만개인 200MB 테이블이 있다고 가정해 봅시다. 단 한 줄의 UPDATE 문으로 이 테이블 전체에서 인덱스되지 않은 열을 업데이트하려면 약 2분정도 걸릴 것입니다. 하지만 WHILE 루프에서 50만 개의 UPDATE 문을 배포하여 동일한 변경을 실행하면 거의 세 시간이 걸릴 것입니다. 하지만 단일한 SQL 문에서 이 결과를 유도해 내기가 불가능한 상황이나 “사용 사례”가 있습니다. 그러한 경우에 대한 한 가지 대안이 이러한 사용 사례의 순서 설명을 저장 프로시저 또는 사용자 정의 함수(UDF)로 캡슐화하는 것입니다.

물론, UDF는 SQL 문 내부에 직접 포함될 수 있습니다. 어떤 점에서는 SQL이 순서 설명을 필요한 만큼 모듈화하는데 함수가 도움이 되므로 함수가 SQL의 표현력을 높여줍니다. 하지만 저장 프로시저는 SQL 문으로는 표현될 수 없으므로 SQL 문 코딩의 관점에서 보면 함수가 좀더 유용한 도구라고 생각됩니다.

하지만 함수는 프로시저를 완벽하게 대체할 수 없습니다. 사실, SQL Server는 프로시저보다 함수에 대해 보다 엄격하게 제한을 둡니다. 예를 들면, 함수에서는 테이블을 업데이트한다든가 하는 글로벌 데이터베이스 상태 변경을 실행할 수 없습니다. 이 외에도 SQL Server는 시스템 정보를 시스템 함수(예: user_name())보다는 저장 프로시저(예: sp_who)로 더 많이 패키지화합니다. SQL 2000 마스터 데이터베이스에서 프로시저와 함수를 놓고 보면, 우리가 생각해낼 수 있는 모든 시스템 정보를 SELECT, UPDATE, INSERT 또는 DELETE하는데 도움이 되는 저장 프로시저는 973개나 되는 반면 구성, 메타데이터, 보안, 시스템 및 시스템 통계 정보를 사용자가 선택(SELECT)은 할 수 있지만 변경은 할 수 없는 함수는 101개 뿐입니다.

시스템 정보를 단일한 SELECT 문으로 캡슐화할 수 있었으면 하고 바라는 경우가 종종 있을 것입니다. 예를 들면, "SELECT spid, login, BlkBy FROM sp_who2 WHERE spid > 50"을 사용하여 사용자 프로세스의 차단 정보만을 볼 수 있다면 좋을 것입니다. 아니면, 단일한 INSERT, UPDATE 또는 DELETE 문으로 데이터베이스 상태에 복잡한 변경을 실행할 수 있었으면 하고 바랄 때도 있을 것입니다. 하지만 안타깝게도 이러한 환상은 절대 실현되지 못할 것입니다. 최소한, SQL 또는 SQL에 포함된 함수 내에서 저장 프로시저를 호출할 수 있게 되기 전까지는 말합니다. SQL Server는 현재 함수 내에서 저장 프로시저를 호출하거나 테이블을 업데이트하는 것을 금지하고 있습니다. 이 제한때문에 우리는 시스템 정보를 사용하거나 단일 SQL 문에서 복잡한 변경을 실행할 수 없습니다. 본 자료는 함수와 프로시저에 걸린 “마법”을 깨뜨려 SQL 문에서 이 둘을 최대환 활용할 수 있도록 하기 위한 의도로 만들어진 시리즈 자료 중 첫 번째입니다.

집합 기반 쿼리

결과 집합처럼 보이는 출력을 반환하는 DBCC 명령 또는 저장 프로시저(sp’s)가 많으며, 이러한 출력이 다른 결과 집합과 직접 조인이 가능하다면 좋을 것입니다. 예를 들어, 이러한 결과 집합을 프로그래밍 방식으로 액세스하여 시스템 관리 작업을 자동화하거나 한 응용 프로그램을 위해 여러 소스에서 데이터를 통합할 수 있다면 좋을 것입니다. DBCC 또는 sp의 다수의 결과 집합을 하나의 SQL 문으로 조인할 수 없고 DBCC 또는 sp에 대해 커서를 선언할 수 없다면 유일한 옵션은 다수의 임시 테이블을 사용하는 것 뿐입니다. 게다가, 이 마지막 방법 역시 DBCC 또는 sp 결과 집합의 모든 열의 데이터 유형을 알고 있어서 임시 테이블을 만들어 DBCC 또는 sp 결과 집합을 그 임시 테이블에 넣을 수 있어야만 가능한 방법입니다. (SELECT INTO를 사용하여 DBCC 또는 sp 결과 집합에서 임시 테이블을 “몰래” 만들수는 없기 때문입니다.) DBCC 또는 sp의 결과 집합이 문서화(예: sp_who2)되지 않았으며 그 스냅샷 중 하나만을 기초로 임시 테이블을 만들면 이후 스냅샷이 더 긴 문자열이나 다른 데이터 형식을 반환할 경우 이 임시 테이블은 손상됩니다. 목록 1에는 먼저 그 필요성은 절실함에도 불구하고 지원은 되지 않는, 두 sp의 결과 집합을 조인하는 집합 기반 SQL 문을 제시하였습니다. 하지만 “최후의 수단”인, 임시 테이블에 의존하는 방법으로 눈길을 돌리지 않을 수 없었습니다.

목록 1. 집합 기반 쿼리와 프로시저 스크립트 비교

--set-based query:
--a much needed, but unsupported, SQL
select * from (Exec sp_who) w inner join 
(Exec sp_lock) l on w.spid = l.spid
where w.spid > 50 and w.blk <> 0

--a batch of scripts:
--temporary tables must be created first before insert
create table #who(spid smallint,ecid smallint,status 
nchar(30),loginame nchar(128),
hostname nchar(128),blk char(5), dbname nchar(128),
cmd nchar(16))
create table #lock(spid smallint,dbid smallint,
ObjId int,IndId smallint,Type nchar(4), 
Resource nchar(16),Mode nvarchar(8),Status nvarchar(5))
insert #who
Exec sp_who
insert #lock
Exec sp_lock
select * from #who w inner join #lock l on w.spid = l.spid
where w.spid > 50 and w.blk <> 0
drop table #who
drop table #lock

여기서 보는 것처럼 SQL 문이 일련의 스크립트보다 훨씬 더 간단하고 효율적입니다. 하지만 시스템 상의 한계때문에 쿼리가 다른 쿼리의 중간 결과에 의지하고 순차적 단계로 나누어져야 할 수도 있습니다. 이러한 한계 중 하나가 SQL 문의 어디서도 DBCC 명령이나 저장 프로시저를 직접 호출할 수 없다는 것입니다. 다음 단락에서는 아주 일반적인 몇몇 시나리오를 살펴 보겠습니다.

사용 사례 1: 프로세스 저장 프로시저 및 DBCC 차단
이 사례는 Kalen Delaney의 저서 Inside Microsoft SQL Server 2000의 926페이지에서 발췌한 것입니다. 새 응용 프로그램이 연결되지 않거나 기존 응용 프로그램이 진행되지 않거나 또는 Enterprise Manager(EM)의 일부 또는 전체가 중단되면 시스템 비상 사태가 발생합니다. 응용 프로그램 “중단”은 대형 프로덕션 SQL Server의 경우에도 그리 드문 일이 아닙니다. 일반적으로 차단이 그 원인이므로 EM을 사용하여 차단/차단된 프로세스와 잠금/잠긴 개체를 찾을 수 있습니다. 하지만 EM이 중단되면 어떻게 해야 할까요? 아니면 차단 체인의 문제가 너무 복잡해서 비상 시 수동으로 신속하게 해결할 수 없는 경우에는 어떻게 해야 할까요? 다행스럽게도 응용 프로그램이 중단되었다고 해도 일반적으로 SQL Server 시스템이 중단된 것을 뜻하지는 않습니다. 따라서 여전히 Query Analyzer와 같은 다른 응용 프로그램에 연결할 수 있습니다. 게다가 SQL Server는 각각 sysprocesses와 syslockinfo 테이블에서 그 소스보다 훨씬 더 읽기 쉬운 형식으로 주요 프로세스와 잠금 정보를 추출하는 sp_who2와 sp_lock를 제공합니다. 심지어는 DBCC INPUTBUFFER(spid)를 사용하면 차단 프로세스가 실행한 마지막 SQL 일괄 처리도 찾아낼 수 있습니다. 여기에서 spid는 그 차단 프로세스의 ID입니다.

따라서 쿼리 분석기에서 대화형으로 SQL 문을 입력하고 차단 프로세스, 차단 응용 프로그램 호스트, 잠긴 개체, 그리고 마지막 SQL 일괄 처리의 세부 사항만 신속하게 검색할 수 있다면 그보다 더 좋은 일이 있겠습니까? 비상 시에 이 결과 집합은 어떤 프로세스에 통지를 하고 어떤 프로세스를 중단할 지에 대한 정확한 결정을 내리는데 큰 도움이 됩니다. 장기적인 관점에서 보면 이 결과 집합은 그 응용 프로그램의 잠금 동작을 새롭게 변형하는 데에도 도움이 됩니다. 다음은 그러한 이상적인 SQL 문입니다. sp_who2의 BlkBy 열에는 차단 프로세스의 spid가 기록된다는 점에 유의하십시오. 프로세스가 차단되지 않았으면 그 BlkBy 열 값은 spid 대신 " . "가 됩니다. 따라서 차단 체인의 근원은 BlkBy는 " . "이지만 spid가 최소한 하나 이상의 BlkBY에 표시되어 있는 프로세스입니다.

select blocking.*, l.*, i.*
from (exec sp_who2) blocking inner join 
(Exec sp_lock) l 
on l.spid = blocking.spid inner join 
(DBCC INPUTBUFFER(all)) i
on l.spid = i.spid
where blocking.BlkBy like '%.%'
and blocking.spid in
(select CAST(blocked.BlkBy as int) from (exec sp_who2)
blocked where blocked.BlkBy not like '%.%')

사용 사례 2: 확장 저장 프로시저
확장 저장 프로시저(이하 xp’s)는 사용자 지정 기능에 “플러그인”하여 SQL Server를 “확장”하도록 SQL Server가 허용하는 몇몇 방법 중 하나입니다. 예를 들면, 전체적으로 또는 부분적으로 범람원에서 50피트 내에 있는 세금 구역의 결과 집합을 반환할 수 있는 xp_intersects라는 xp를 만들었습니다. 제가 xp_intersects를 보험 테이블, 허가증 테이블, 소유자 테이블 및/또는 시장 가치 테이블에 임의로 손쉽게 조인할 수 있다면 이러한 xp는 SQL Server를 위성 정보 시스템(GIS)과 같은 수직적 응용 프로그램의 영역으로 밀어넣는 좋은 예가 될 것입니다. 다음 SQL 문은 SQL Server를 확장하는 단순하면서도 우수한 방법입니다.

SELECT t.taxlot_id, i.*, v.*
From (Exec xp_intersects('polygon_100_year_flood', 
'taxlots', 50)) t inner join insurance i on t.taxlot_id = 
i.taxlot_id inner join market_value v on
t.taxlot_id = v.taxlot_id 

사용 사례 3: XML 데이터 소스
XML은 빠르게 사실상의 데이터 교환 표준이 되었을 뿐만 아니라 직접적인 데이터 소스로도 유용합니다. 예를 들면, 공급 업체는 HTTP를 통해 XML 문자열로 구매 주문을 받을 수 있습니다. 이 XML 문자열은 제품 ID와 수량을 인코딩할 것입니다. 공급자의 응용 프로그램이 이 XML 문자열을 구입 제품이 들어 있는 테이블처럼 처리하여 그 공급자의 카탈로그 및 저장소 테이블과 조인시켜 제품 선적이 자동으로 처리되도록 하면 간편할 것입니다. SQL Server 2000의 새 행집합 공급자 OPENXML은 XML 문서를 통해 결과 집합을 반환할 수 있다는 것을 알고 있을 것입니다. 하지만 OPENXML을 사용할 경우 이 구매 주문 XML 문자열이 다른 테이블에 조인하려면 다음 세 단계를 거쳐야만 합니다.

-- parameter @XMLDoc varchar(8000) contains XML string
DECLARE @iDoc int
Exec sp_xml_preparedocument @iDoc OUTPUT, @XMLDoc
SELECT * FROM OpenXML(@iDoc, '/ROOT/Order',0) WITH
(ProductID int, Quantity int) o inner join catalog c
on o.ProductID = c.ProductID inner join warehouse w
on c.WarehouseID = w.WarehouseID
Exec sp_xml_removedocument @iDoc

sp_xml_preparedocument와 sp_xml_removedocument는 각각 메모리에서 XML 문자열의 구문을 검색하고 그 메모리를 다시 할당하는 xp's입니다.

XML 단계를 sp_OpenXML와 같은 프로시저로 그룹화하여 이러한 단계를 단일한 SQL 문으로 코드화할 수 있다면 좋지 않겠습니까?

-- parameter @XMLDoc varchar(8000) 
SELECT *
FROM (Exec sp_OpenXML(@XMLDoc) o inner join catalog c
on o.ProductID = c.ProductID inner join warehouse w
on c.WarehouseID = w.WarehouseID)

집합 기반 접근법

집합 기반 프로세스의 기능을 완벽하게 활용하기 위해서는 지금까지 설명한 사용 사례에 맞는 솔루션을 만드는데 도움이 되는 방법이나 도구를 찾아야 합니다. 이 도구는 SQL 문에 사용될 수 있어야 하고 sp, xp, OPENXML 및 DBCC 명령에서 직접 결과 집합을 반환할 수 있어야 합니다. 본 자료의 나머지 부분에서는 가능성 있는 두 도구를 살펴보고 어떤 도구가 위의 두 가지 요구 사항을 모두 충족시키는지 알아 보겠습니다.

UDF는 언뜻 보면 논리적인 선택으로 여겨질 수 있습니다. 사실상 UDF는 SQL 문에 사용할 수 있는 유일한 사용자 확장입니다. 게다가 UDF는 테이블 변수나 스칼라 변수 중 하나를 반환할 수 있습니다. 예를 들어 세 번째 사용 사례를 충족시키려면 다음과 같은 실행을 하고 싶어질 것입니다.

--Function that encapsulates xp's and OPENXML
--creation of function udf_xml succeeds
Create function udf_xml(@XMLDoc varchar(8000))
Returns @t table(ProductID int, Quantity int)
as
begin
declare @iDoc int
Exec sp_xml_preparedocument @iDoc OUTPUT, @XMLDoc
INSERT @t
SELECT * FROM OPENXML(@idoc, '/ROOT/Order',0) 
  WITH (ProductID int, Quantity  int)
Exec sp_xml_removedocument @iDoc
return
end
GO
--now join result set of udf_xml() in a SQL statement
--execution of function udf_xml fails
DECLARE @XMLDoc varchar(8000)
set @XMLDoc =
'<ROOT>
  <Order ProductID="11" Quantity="12"/>
  <Order ProductID="42" Quantity="10"/>
  <Order ProductID="72" Quantity="3"/>
</ROOT>'
select * from udf_xml(@XMLDoc) o inner join catalog c
on o.ProductID = c.ProductID inner join warehouse w
on c.WarehouseID = w.WarehouseID
GO

-- Error message output
Server: Msg 557, Level 16, State 2, 
Procedure udf_xml, Line 6
Only functions and extended stored procedures 
can be executed from within a function.

udf_xml은 XML 결과 집합을 반환하는 세 단계를 성공적으로 캡슐화하지만(그리고 조인 SQL 문도 아주 간단하지만) udf_xml 실행은 실패합니다. 사실, 함수 자체만으로는 여기 제시된 어떤 사용 사례도 해결할 수 없습니다. 함수에는 다음과 같은 제약이 따르기 때문입니다.

  • 함수는 저장 프로시저를 실행할 수 없습니다. 함수는 함수와 일부 xp's는 실행할 수 있지만 sp's는 실행할 수 없습니다. 이러한 한계 때문에 함수는 사용 사례 1과 3을 해결할 수 있는 후보에서 즉시 탈락됩니다.
  • 함수는 임시 테이블 또는 다른 어떤 형태의 테이블도 만들 수 없습니다. xp 결과 집합을 반환하려면 함수는 그 결과 집합을 어딘가에는 저장할 수 있어야 합니다. 테이블이 가장 일반적인 선택 방법입니다. 하지만 안타깝게도 함수는 글로벌 데이터베이스 상태를 변경할 수 없습니다. 그 때문에 글로벌 데이터베이스 상태를 변경할 수 있는 임시 또는 영구 테이블을 만드는 것도 제한됩니다.
  • 함수는 임시 테이블을 액세스할 수 없습니다. 글로벌 임시 테이블이 미리 만들어져 있다 하더라도 SQL Server는 여전히 함수에서 그 테이블이나 기존의 다른 임시 테이블로의 데이터 삽입을 허용하지 않습니다.
  • 함수는 기존 테이블에 삽입을 할 수 없습니다. 함수 외부에 영구 테이블을 만들면 어떨까라는 생각도 할 수 있습니다. 하지만 함수에서 기존 영구 테이블로의 삽입 역시 글로벌 데이터베이스 상태를 변경하는 것으로 간주됩니다.
  • 기존 DBCC, sp 또는 xp 실행 결과 집합을 테이블 변수에 삽입할 수 없습니다. 테이블 변수를 사용하여 결과 집합을 저장하는 방법은 어떨까요? 안타깝게도 EXECUTE를 사용하여 테이블 변수에 데이터를 삽입할 수 없습니다. 하지만 EXECUTE는 함수 내에서 DBCC, sp 및 xp가 포함되는 SQL 문자열을 발행할 수 있는 유일한 방법입니다. 이 마지막 한계에 다다르자 우리는 UDF는 위 사용 사례에 대한 해답이 아니라는 결론을 내리지 않을 수 없었습니다.

마지막 방법 OPENQUERY

제 조사에 따르면 OPENQUERY가 SQL 문에서 sp, xp 및 DBCC 결과 집합을 반환하는 유일한 방법으로 여겨집니다. 하지만 OPENQUERY 역시 완벽하지는 않습니다. 예를 들면, OPENQUERY를 사용하면 다음 예에서 볼 수 있는 것처럼 sp_who 결과 집합은 손쉽게 반환할 수 있지만 sp_who2 결과 집합은 반환할 수 없습니다.

--openquery returns the result set of sp_who just fine
select * from openquery(csherts, 'Exec sp_who')
go
(14 row(s) affected)

--openquery finds no result set from sp_who2
select * from openquery(csherts, 'Exec sp_who2')
go
Server: Msg 7357, Level 16, State 2, Line 1
Could not process object 'Exec sp_who2'. 
The OLE DB provider 'SQLOLEDB' indicates that 
the object has no columns.

OPENQUERY는 SELECT 문의 FROM 절에 들어갈 수 있으므로 첫 번째 요구 사항은 만족시킵니다. OPENQUERY를 사용하면 UDF는 sp나 xp, OPENXML 또는 DBCC를 간접적으로 호출할 수 있습니다. FROM 절 외에도 함수는 SQL의 어디서나 사용될 수 있습니다. 두 번째 요구 사항의 경우에는, OPENQUERY는 일부 sp’s에 대해서만 실행되며 xp's나 DBCC와는 실행되지 안습니다. 사실, OPENQUERY가 입력 SQL 문자열을 기초로 한 열 이름과 출력 결과 집합 유형을 알 수 없으면 이 쿼리는 실패하며 “이 개체에는 열이 없습니다”라고 응답합니다. OPENXML의 경우 OPENQUERY는 다음 코드 블록의 예에서 볼 수 있는 것처럼 처음에는 모든 것이 잘 진행된다는 느낌을 줄 수 있습니다. 하지만 두 번째 예를 자세히 살펴 보면 OPENQUERY는 OPENXML에는 현실적이지 않다는 것을 알 수 있습니다. 이는, XML 문자열은 사실상 변수로 구성되는 경우가 많은데 OPENQUERY는 변수를 인수로 사용하지 않기 때문입니다.

그럼에도 불구하고 OPENQUERY와 UDF 조합은 위 세 사용 사례를 모두 지원할 수 있는 가능성이 있습니다. 다시 말하면 OPENQUERY만이 sp’s와 함수에 걸린 마법을 깰 수 있는 유일한 도구입니다. 본 시리즈의 다음(두 번째) 자료에서는 OPENQUERY의 동작을 자세히 설명하고 그 한계를 간단하게 요약한 다음 그러한 한계를 극복하는 방법을 제시하겠습니다. 그리고 OPENQUERY를 사용하여 본 자료에서 설명한 사용 사례를 구현해 보겠습니다.

-- Example 1 OPENQUERY works for OPENXML only if XML 
-- is a constant string
-- XML specified in the constant argument to OPENQUERY
select * from openquery(csherts,
'
declare @iDoc int
Exec sp_xml_preparedocument @iDoc OUTPUT, ''<ROOT>
      <Order ProductID="11" Quantity="12"/>
      <Order ProductID="42" Quantity="10"/>
      <Order ProductID="72" Quantity="3"/>
</ROOT>''
SELECT * FROM OPENXML(@idoc, ''/ROOT/Order'',0) 
              WITH (ProductID int, Quantity  int)
Exec sp_xml_removedocument @iDoc
')
go
-- Output
(3 row(s) affected)

--Example 2 XML concatenates with OPENXML steps in a 
--variable argument to OPENQUERY. Illustrates that 
--OPENQUERY does not accept variable arguments
DECLARE @XMLDoc varchar(8000)
set @XMLDoc =
'<ROOT>
  <Order ProductID="11" Quantity="12"/>
  <Order ProductID="42" Quantity="10"/>
  <Order ProductID="72" Quantity="3"/>
</ROOT>'
set @XMLDoc = '
declare @iDoc int
Exec sp_xml_preparedocument @iDoc OUTPUT, ''' +
 @XMLDoc + '''
SELECT * FROM OPENXML(@idoc, ''/ROOT/Order'',0) 
              WITH (ProductID int, Quantity  int)
Exec sp_xml_removedocument @iDoc
'
select * from openquery(csherts,@XMLDoc)
go
-- Output
Server: Msg 170, Level 15, State 1, Line 15
Line 15: Incorrect syntax near '@XMLDoc'.

[지난 호의 관련 자료: Andrew Zanevsky의 "Granting Users' Wishes with UDFs" (2000년 9월), "Inline Table-Valued Functions" (2000년 10월), "Multi-Statement Table-Valued Functions" (2000년 11월), "UDF Performance… or Lack of It" (Anton Jiline 공저, 2001년 10월). Tom Moreau의 "Dynamic DTS Tasks and OPENROWSET" (2001년 1월), "How Do You Feed an Array to a Stored Procedure?" (2002년 4월). Scott Whigham의 "How to Write your Own System Functions" (2001년 12월).—편집자 주.]

QUERY1.SQL (영문) 다운로드

이 글은 스프링노트에서 작성되었습니다.

2010. 6. 4. 01:18

SQLDMO

SQL SERVER 2005 이상

Using DMO to Restore a Database

http://www.sqlservercentral.com/columnists/awarren/sqldmorestore.asp

이 글은 스프링노트에서 작성되었습니다.


'Common Admin' 카테고리의 다른 글

RML Utilities for SQL Server  (0) 2010.08.23
SQL 2008 -New DataType-Date  (0) 2010.06.04
SQL Server의 Procedure Cache 사이즈  (0) 2010.06.04
Admin::master db rebuild 방법  (0) 2010.06.04
2010. 6. 4. 01:18

Install Tip

 출처: http://www.nextstep.co.kr/69

  참조:성능 향상을 위한 SQL Server 구성

 

1. 인스톨에 관한 팁

SQL Server를 인스톨 할 때 선택한 정렬 순서(sort order)가 성능에 영향을 끼칠 수 있다. 정렬 순서 가운데에
는 비록 그 결과가 클라이언트 프로그램에서 문제를 일으키긴 하지만 이진 정렬이 가장 속도가 빠르다. 디폴
트로 선택되는 "사전 순서(dictionary order), 대소문자 구분 안함(case-insensitive)"이 그 다음으로 빠르며 아
마 여러분은 보통 이것을 사용할 것이다. "사전 순서, 대소문자 구분 안함, 액센트 구분 안함(accent-
insensitive), 대문자 선호(uppercase preference)"와 "사전 순서, 대소문자 구분함(case-sensitive)"는 속도면
에서 뒤쳐진다. 프로그램의 성능과 요구사항에 가장 적합한 정렬 순서를 선택하도록 한다. [6.5, 7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/default.asp?
URL=/library/psdk/sql/8_ar_da_10.htm)

*****

SQL Server를 인스톨 할 때 선택하는 네트워크 라이브러리도 서버와 클라이언트 간의 통신 속도에 영향을 준
다. 사용 가능한 세 개의 네트워크 라이브러리 중에서 TCP/IP가 가장 빠르며 멀티 프로토콜이 가장 느리다.
TCP/IP의 속도가 빠르므로 서버와 클라이언트 모두 TCP/IP를 사용하는 것이 좋으며 사용하지 않는 라이브러
리는 불필요한 오버헤드만 가중시키므로 인스톨 하지 않는 편이 바람직하다. [6.5, 7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/default.asp?
URL=/library/psdk/sql/1_server_6.htm)

*****

일반적으로 여러분은 가장 최신의 SQL Server 서비스 팩을 인스톨 하고 싶을 것이다.
사실상 SQL Server 6.5와 7.0의 서비스 팩에서 성능에 영향을 줄 수 있는 버그는 모두 해결된 상태이다. 그러
나 잘 아는 바와 같이 새로운 서비스 팩이 나오자 마자 성급하게 인스톨 하는 것은 좋지 않으며 최소한 2~4주
정도 SQL Server 뉴스그룹 등을 관찰하면서 새로운 서비스 팩이 중대한 문제를 안고 있지는 않은지 확인하는
것이 좋다. [6.5, 7.0, 2000]




2. 파일 위치에 관한 팁

master, msdb 그리고 model 데이터베이스는 운영 환경에서 그다지 많이 사용되지는 않기 때문에 이들 데이터
베이스의 물리적인 위치는 별로 중요하지 않다. [6.5, 7.0, 2000]

*****

데이터베이스 파일(.mdf)과 로그 파일(.ldf)을 별도의 디스크 어레이에 위치시켜서 읽기와 쓰기 작업이 충돌하
는 경우가 감소하도록 서로 분리시킨다. [6.5, 7.0, 2000]

데이터베이스 파일(.mdf)을 저장할 때에는 RAID 10 어레이에서 가장 뛰어난 성능을 보여준다. RAID 10 어레이
가 너무 비싸다면 RAID 5 가 그 다음으로 좋은 선택이 될 수 있다. 각 RAID 어레이는(5 또는 10) 컨트롤러가 지
원하는 한 여러 개의 물리적인 디스크를 어레이 안에 가질 수 있다. 이런 점으로 해서 어레이의 각 물리적 드
라이브에 읽기와 쓰기 작업이 동시에 진행될 수 있으며 디스크 I/O 처리 능력이 크게 늘어나게 된다.

*****

데이터베이스 로그 파일(.ldf)을 저장할 때에는 RAID 1 어레이(미러링)에 저장하는 것이 가장 최적의 성능을
보이는 경우가 많다. 여기서는 RAID 1 어레이에 오직 하나의 로그 파일이 존재한다고 가정하였다. RAID 1 어레
이에 하나의 로그 파일만 존재하면 파일을 순차적으로 쓸 수 있기 때문에 로그 기록 작업이 빨라지게 된다.

그러나 만약 RAID 1 어레이를 공유하는 로그 파일이 여러 개 있다면(여러 개의 데이터베이스로부터) RAID 1
어레이를 사용하는 장점이 거의 사라진다. 로그 기록 작업은 여전히 순차적으로 이루어 지지만 동일한 어레이
에 여러 개의 로그 파일이 존재하면 이 어레이는 더 이상 순차적으로 기록할 수 없고 랜덤하게 쓰기 작업을 해
야 하므로 RAID 1 어레이의 이점을 상쇄해 버리기 때문이다.

그러나 RAID 1 어레이가 RAID 5 어레이보다 랜덤 쓰기를 더 많이 처리할 수 있다면 RAID 5 어레이 보다는
RAID 1 어레이가 아직도 더 좋다고 볼 수 있다. 확실하게 알기 위해서 여러분의 하드웨어를 확인해 보기 바란
다. 다른 방법으로는 데이터베이스들의 로그를 각각 별도의 RAID 1 어레이에 저장하는 것이다. 또는 RAID 1
과 RAID 5의 장점만을 모은 RAID 10 어레이에 로그 파일을 저장하는 것도 생각해 볼 수 있다. 많은 비용이 들
어가겠지만 최고의 성능을 제공한다. [6.5, 7.0, 2000]

*****

데이터베이스의 규모가 매우 크고 작업량도 많다면 성능을 향상 시키기 위해서 여러 개의 파일을 사용해 볼
수 있다. 예를 들어 조회 작업이 매우 많은 천만건의 레코드를 가진 테이블이 하나 있다고 하자. 이 테이블이
하나의 데이터베이스 파일에 존재하고 있다면 레코드를 순차적으로 읽기 위해서 SQL Server에서는 단지 하나
의 쓰레드만을 사용한다. 그러나 만약 이 테이블이 세 개의 물리적 파일로 분산되어 있다면 테이블을 순차적
으로 읽을 때 SQL Server는 세 개의 쓰레드(한 파일에 하나씩)를 사용하므로 작업 속도가 훨씬 빨라지게 된
다. 게다가 각 파일이 별도의 디스크나 디스크 어레이에 존재하고 있다면 성능은 한층 배가된다.

본질적으로 큰 테이블이 여러 개의 물리적인 파일로 나누어 질수록 성능이 높아질 가능성이 더 커진다. 물론
서버의 I/O가 한계 값에 도달하게 되면 더 이상 쓰레드가 추가되어도 성능 향상에는 별로 도움이 되지 못하게
된다. 하지만 서버의 I/O가 한계 값에 도달할 때 까지는 쓰레드(그리고 파일)가 늘어날수록 성능도 함께 증가
하게 된다. [7.0, 2000]




3. 서버 설정에 관한 팁

SQL Server 6.5를 사용하고 있다면 서버의 물리적인 RAM에 따라서 8MB 또는 16MB로 결정되는 디폴트 메모
리 세팅을 그대로 사용하는 것과 같이 DBA 들이 흔히 저지르는 실수를 반복하지 말기 바란다. 이 숫자는 NT
서버의 여유 메모리에서 얼마만큼의 RAM을 SQL Server가 사용할 수 있는가를 지정하는 것이다. 필자는 RAM
이 2GB인 시스템을 포함하여 디폴트 메모리로 설정된 SQL Server 6.5 시스템을 많이 보았다.

SQL Server 6.5는 7.0이나 2000 버전과는 달리 메모리를 동적으로 설정하는 기능을 가지고 있지 않기 때문에
DBA가 직접 늘려 주어야 한다. [6.5]
(마이크로소프트의 보다 자세한 정보 : http://www.microsoft.com/technet/SQL/Technote/sqliopt.asp)

*****

작업 내용을 확실히 이해하고 있고 지금 하고 있는 SQL Server 의 설정 변경 작업이 성능 향상에 도움이 된다
는 공정한 실험 결과를 가지고 있지 않는 한 함부로 서버의 성능에 영향을 줄 수 있는 SQL Server 의 설정 사
항을 변경하지 말기 바란다. 많은 경우에 있어서 문제를 해결하기 보다는 오히려 더 많은 문제를 일으킬 가능
성이 크다. [6.5, 7.0, 2000]

*****

SQL Server는 자동으로 튜닝이 되긴 하지만 SQL Server가 내부적인 세팅의 최적 값을 찾아내기 까지는 SQL
Server가 겪는 활동의 종류와 레벨에 따라서 대략 수 시간정도 소요된다. SQL Server 서비스가 처음 기동 되
면 SQL Server는 디폴트 환경 세팅으로부터 시작하게 된다. 데이터베이스에 대한 작업이 진행되고 쿼리가 실
행되면서 SQL Server는 자체적으로 정밀하게 튜닝을 하게 되고 시간이 흐를 수록 성능이 증가한다.
이런 점에서 보았을 때 SQL Server가 자체적으로 튜닝할 수 있을 때까지는 정확한 퍼포먼스 모니터 결과를 얻
는 것을 기대하지 않는 편이 좋다. SQL Server가 튜닝될 수 있도록 mssqlserver 서비스가 기동 된 후에 어느
정도의 시간 여유를 주도록 한다. [7.0, 2000]

*****

SQL Server의 옵션은 일반 옵션과 고급 옵션으로 구분된다. sp_configure를 사용해서 고급 옵션을 변경하려
면 고급 옵션을 사용 가능하게 하는 스토어드 프로시저를 먼저 실행해야 한다. 이 때 사용되는 명령은
sp_configure "show advanced options", 1 이다. [6.5, 7.0, 2000]

*****

여러 개의 CPU가 장착된 시스템이 100% 풀 가동중일 때 CPU 사용도를 줄일 수 있는 다른 방법이 없는 경우에
는 NT의 파이버(fibers)를 사용해서 성능을 향상 시킬 수 있다. 파이버는 쓰레드와 유사하게 동작하는 쓰레드
의 서브 컴포퍼넌트이다. 파이버를 사용하면 여러 개의 CPU를 사용하는 시스템에서 CPU간의 스위치 시에 오
버헤드가 적다는 장점이 있다.

CPU가 최대로 사용되는 상황이 아니라면 파이버를 사용해도 별 효과는 없으므로 이 옵션을 선택하지 않도록
한다. 또한 이렇게 설정하기 전과 후의 성능 변화도 자세하게 테스트 해야 한다. 이 옵션은 SQL Server
의 "Properties" 의 "Processor" 탭에서 찾을 수 있다. [7.0, 2000]
(마이크로소프트의 보다 자세한 정보 :
http://msdn.microsoft.com/library/techart/storageeng.htm#storageeng_procplan)

*****

고속의 디스크 컨트롤러가 장착된 서버에서는 SQL Server 환경 설정에서 "Max Async IO"를 변경함으로써
I/O 성능을 향상 시킬 수 있다. 디폴트는 32 이며 최대 값은 255 이다. 여러분의 서버에서 최적의 값을 찾기 위
해서는 여러 가지로 변경해 가면서 테스트 해봐야 한다.

적절한 "Max Async IO" 값은 대략 동시에 I/O가 가능한 물리적인 드라이브 개수에 2 또는 3을 곱한 값이다.

이 옵션을 변경한 다음에는 매번 SQL Server를 재기동 해야 하므로 운영중인 서버에서는 테스트하지 말기 바
란다. 이 값을 너무 높게 설정하면 디스크 작업의 적체가 발생하는데 퍼포먼스 모니터로 보면 Physical Disk
객체의 Disk Queue Length 가 물리적 드라이브마다 2를 넘어서게 되며 이것은 I/O에서 병목 현상이 발생함을
의미한다. [6.5, 7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://support.microsoft.com/support/kb/articles/Q112/5/39.asp)

*****

삽입, 갱신, 삭제 작업을 많이 하는 OLTP 프로그램이 매우 활발하게 실행된다면 "recovery interval"의 디폴트
값인 0는 적절하지 않다(0은 SQL Server가 적절한 recovery interval을 결정한다는 것을 의미함). 퍼포먼스 모
니터로 관찰했을 때 규칙적으로 디스크 쓰기 작업이 100%까지 이르는 경우가 발생하면(체크포인트 시에 발생
되는 것으로 추정) "recovery interval"을 5 정도로 높게 설정해야 한다. [6.5, 7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/default.asp?
URL=/library/psdk/sql/8_tr_01_22.htm)

*****

데이터베이스의 모든 테이블이 SQL Server의 버퍼에 들어가지는 않고 다른 것에 비해서 매우 자주 사용되는
작은 테이블이 하나 이상 존재한다면 이 테이블들을 SP_TABLEOPTION PINTABLE 옵션을 사용하여 버퍼에 고
정시키는 것을 고려해 보도록 한다. 이렇게 하면 테이블이 일단 버퍼에 로드된 후에는 계속해서 강제적으로
버퍼에 머물게 된다.

그러면 이들 테이블이 사용될 때 필요한 디스크 I/O가 감소하게 된다. 큰 테이블을 메모리에 고정시키면 SQL
Server가 보다 유용하게 사용할 수 있는 중요한 버퍼 영역을 차지해 버리게 되므로 주의하여야 한다. [6.5,
7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/default.asp?
URL=/library/psdk/sql/sp_ta-tz_3.htm)

*****

SQL Server와 통신하는 클라이언트의 네트워크 패킷 크기는 디폴트로 4096 바이트이다. 대부분의 경우 이 값
은 최적의 값이지만 특별한 경우에는 이것을 변경할 필요가 있다. 만약 클라이언트가 규칙적으로 큰 텍스트
나 이미지 데이터를 SQL Server로 전송한다거나, 대규모의 BCP 또는 DTS 작업을 수행하는 경우 패킷 크기를
늘려주면 오고 가는 네트워크 패킷의 숫자가 줄어들므로 성능을 향상시킬 수 있다. 반대로 응용 프로그램이
작은 데이터만을 주고 받을 때에는 패킷 크기를 줄여줌으로써 응답성을 향상시킬 수 있다.

SQL Server에서 설정한 패킷 크기는 클라이언트 소프트웨어에 의해서 변경될 수 있음을 기억해야 한다. 여러
분이 네트워크 트래픽 분석에 매우 익숙하고 작업 후의 성능 변화를 테스트할 수 있는 능력이 있는 경우에만
이 값을 변경하는 것이 좋다. [6.5, 7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/psdk/sql/1_server_48.htm)

*****

서버에 물리적인 RAM이 충분한 상태에서 해쉬나 정렬 작업과 같이 메모리를 집중적으로 사용하는 쿼리와 동
시에 실행되는 쿼리가 많다면 SQL Server 옵션에서 "min memory per query" 옵션을 디폴트인 1024K 보다 늘려
보도록 한다. SQL Server가 자동으로 할당하는 최소한의 메모리를 지정하는 것으로 이 값을 늘려주면 메모리
를 많이 사용하는 쿼리의 성능이 향상된다.

반대로 이 옵션을 너무 크게 설정하면 쿼리가 오히려 느려지게 된다. SQL Server가 이 값에 지정한 만큼의 메
모리를 할당하거나 "query wait" 옵션에 지정한 값이 초과될 때까지는 쿼리가 실행되지 않기 때문이다. 여러분
의 환경에 맞는 적절한 값을 찾기 위해서는 여러 가지로 변경해 가면서 테스트 해야 한다. [7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/psdk/sql/1_server_46.htm)

*****

SQL Server가 OLTP 프로그램만을 수행하고 OLAP 프로그램은 전혀 사용하지 않는다면 "max degree of
parallelism"을 1로 설정하여 병렬 처리를 하지 않도록 해 본다. 디폴트는 "0"이며 모든 CPU에 걸쳐서 병렬 처
리를 하도록 되어 있다. CPU가 하나인 경우에는 "max degree of parallelism" 값은 무시된다.

여러 개의 CPU가 있는 경우 디폴트로 병렬 처리를 하게 되는데 쿼리 옵티마이저가 각 쿼리에 대해서 병렬 처
리가 가능한지 평가하는데 약간의 오버헤드가 발생한다. 대부분의 OLTP 서버에서는 실행되는 쿼리의 특성
상 병렬 처리가 불가능한 경우가 많다. 이렇기 때문에 쿼리 옵티마이저는 각 쿼리가 병렬 처리로부터 이득을
볼 수 있을지 평가하기 위해서 시간을 소비하게 된다. 만약 쿼리가 병렬로 실행될 필요가 없다는 것을 미리 알
고 있는 경우에는 이 기능을 OFF 시켜서 쿼리의 평가에 걸리는 시간을 줄임으로써 약간의 오버헤드를 감소시
킬 수 있다.

물론 SQL Server에서 실행되는 쿼리의 성격상 병렬 처리의 장점을 이용할 수 있는 것이라면 병렬 처리를 OFF
시킬 필요는 없다. 이 기능을 사용했을 때 여러분의 환경에서 SQL Server의 성능 향상에 도움이 될지 아니면
해가 될지를 알기 위해서는 직접 테스트를 해봐야 한다. [7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/psdk/sql/1_server_42.htm)

*****

서버를 SQL Server 전용으로 사용하고 있고 CPU가 여러 개 설치되어 있다면 SQL Server 옵션가운데 "priority
boost"를 디폴트인 0에서 1로 변경해 보도록 한다. 이렇게 하면 SQLServer의 sqlservr.exe 프로세스가 다른
프로세스보다 스케줄링 측면에서 높은 우선 순위(priority)를 부여 받게 된다. CPU가 여러 개인 시스템에서는
프로세스 우선 순위가 15에서 24로 변경되며 SQL Server의 성능이 약간 향상된다. 운영 환경에서 이 값을 사
용하기 전에 변경하기 전과 후의 성능 변화를 테스트하여 SQL Server에 도움이 되는지 확인해야 한다. [7.0,
2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/psdk/sql/1_server_50.htm)

*****

서버를 SQL Server 전용으로 사용하고 있고 CPU가 여러 개 설치되어 있다면 SQL Server 옵션 가운데 "time
slice"를 변경해 보도록 한다. 이 값은 SQL Server에 의해서 중단되지 않고 사용자 프로세스가 실행될 수 있는
시간(milliseconds)을 의미한다. 일반적으로 사용자 프로세스는 CPU 시간을 얼마만큼 사용할지를 자체적으
로 결정하여 적절하게 스케줄링 한다. 그러나 사용자 프로세스가 실행되는 시간이 "time slice" 값을 넘어서게
되면 SQL Server는 이 프로세스가 멈추었다고 판단하여 강제로 종료시킨다.

"time slice"의 디폴트 값은 100 milliseconds이다. "time slice"를 너무 작게 설정하면 오랫동안 수행된다는 이유
만으로 강제적으로 종료된 프로세스를 다시 스케줄링해서 실행해야 하기 때문에 추가적인 오버헤드가 발생
하여 시스템의 성능이 저하된다. "time slice"가 너무 크면 비정상적으로 멈춰버린 프로세스가 CPU 시간을 허
비하는 문제가 발생한다.

이 값을 어떻게 설정해야 할까를 결정하는 기준이 되는 중요한 요소가운데 하나는 CPU 성능이다. 만약 CPU
가 400MHz 이하의 속도라면 디폴트 값을 바꾸지 않는 것이 좋다. CPU가 400~600MHz의 속도를 가지고 있다
면 "time slice"는 200 milliseconds가 적당하고 600MHz 이상이라면 300 milliseconds로 설정해 보기 바란다. 이
값을 실제로 사용하기 전에 변경 전과 후에 SQL Server의 성능이 어떻게 변하게 되는지 테스트 해 봐야 한다.
[7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/psdk/sql/1_server_64.htm)

*****

서버를 SQL Server 전용으로 사용한다면 SQL Server 옵션 가운데 "max worker threads"가 적절하게 설정되어
있는지 확인해 보기 바란다. 디폴트 값은 255이다. 이 옵션은 Windows NT 4.0에서 sqlservr.exe 프로세스에서
사용 가능한 작업 쓰레드(worker thread)의 수를 지정한다. 만약 동시 사용자가 255명 이하라면 각 사용자는
하나의 작업 쓰레드를 사용할 것이다. 그러나 동시 사용자가 255명을 넘어서면 SQL Server는 쓰레드 풀링을
사용하게 되는데 한명 이상의 사용자가 하나의 작업 쓰레드를 공유하게 된다. 쓰레드 풀링은 SQL Server에 의
해서 사용되는 시스템 리소스를 줄여주지만 대신 SQL Server를 사용하기 위한 사용자 커넥션의 경쟁이 증가
하게 된다.

최적의 성능을 위해서는 "max worker threads"를 서버를 사용하는 최대 사용자 수에 5를 더한 값으로 설정한
다. 이렇게 하면 동시 사용자 수가(더하기 5) 255 이하라면 SQL Server가 리소스를 다른 곳에 사용할 수 있도
록 해 주며 동시 사용자 수가(더하기 5) 255명을 넘어선다면 사용자 커넥션이 리소스를 차지하기 위해서 경쟁
할 것을 걱정할 필요가 없다. 하지만 추가적인 작업 쓰레드가 물리적인 RAM을 사용한다는 점을 잊
어서는 안된다. 따라서 이미 서버의 물리적인 RAM이 한계 치에 도달했다면 "max worker threads"를 디폴트인
255 이상으로 설정하지 말기 바란다. 그러나 물리적인 RAM에 여유가 있다면 위에서 설명한 것처럼 "max
worker threads"를 키워서 최대한 활용하도록 한다.

이 옵션을 운영 환경에서 사용하기 전에 변경 전과 후의 성능을 테스트하여 SQL Server가 이득을 볼 수 있는
지 확인해 보아야 한다. [7.0, 2000]
(마이크로소프트의 보다 자세한 정보 : http://msdn.microsoft.com/library/psdk/sql/1_server_44.htm)




4. Tempdb I/O에 관한 팁

SQL Server의 tempdb 데이터베이스가 응용 프로그램에 의해서 과도하게 사용된다면 tempdb를 별도의 디스
크 어레이에 위치시키도록 한다(RAID 1 또는 RAID 10 같은). [6.5, 7.0, 2000]

*****

SQL Server가 설치된 다음에 tempdb 데이터베이스를 옮기고자 한다면 아래의 스크립트를 사용하여 적절한
위치로 이동시키면 된다.

USE master
go
ALTER DATABASE tempdb MODIFY FILE (NAME = tempdev, FILENAME = E:    empdb.mdf)
go
ALTER DATABASE tempdb MODIFY FILE (NAME = templog, FILENAME = E:    emplog.ldf)
go

여기서 NAME은 tempdb 데이터베이스와 로그 파일의 논리적인 이름이며 FILENAME은 tempdb 파일의 새로운
위치를 가리킨다. [7.0, 2000]

*****

응용 프로그램에서 tempdb 데이터베이스를 많이 사용하여 디폴트로 설정된 크기보다 커진다면 tempdb의 디
폴트 크기를 응용 프로그램에서 실제로 사용되는 크기에 가깝게 늘리도록 한다. SQLServer 서비스
(mssqlserver)가 기동 될 때 마다 tempdb 파일이 디폴트 크기로 재생성 되기 때문이다. tempdb 파일이 사용 중
에 커질 수는 있지만 이 작업을 위해서 어느 정도의 리소스가 소비된다. SQL Server가 기동 될 때 tempdb 파일
의 크기를 적절하게 설정하면 운영 중에 tempdb가 확장되면서 발생하는 오버헤드를 걱정할 필요가 없다.
[7.0, 2000]




5. Cursor에 관한 팁

가능하다면 SQLServer의 커서를 사용하지 않는 것이 좋다. 일반적으로 커서는 SQL Server의 리소스를 많
이 잡아 먹을 뿐 아니라 프로그램의 성능과 확장성을 떨어뜨리게 된다. 만약 레코드 단위로 처리를 해야 하는
경우라면 커서 대신에 다른 방법을 찾아보기 바란다. 클라이언트에서 작업을 처리하거나, 서버에서 tempdb
데이터베이스의 테이블을 이용해도 되고 correlated sub-query를 사용하는 것도 좋은 대안이 될 수 있다. 때로
는 커서를 대신할 수 있는 방법이 전혀 없는 경우도 물론 있다. [6.5, 7.0, 2000]
(마이크로소프트의 추가 정보 : http://msdn.microsoft.com/library/default.asp?
URL=/library/psdk/sql/8_con_07.htm)

*****

각 레코드 별로 처리를 해야 하지만 가져오고자 하는 레코드의 개수가 많지 않다면 서버 쪽의 커서를 사용하
지 않도록 한다. 그 대신 전체 레코드를 클라이언트로 넘긴 다음 클라이언트에서 레코드 별로 필요한 작업을
수행한 후 결과를 다시 서버로 보내는 형식으로 처리한다. [6.5, 7.0, 2000]

*****

커서를 사용할 수 밖에 없는 상황이라면 forward-only 및 read_only 커서를 사용하는 것이 좋다. 이 커서는
SQL Server에 가장 적은 오버헤드를 발생시킨다. [6.5, 7.0, 2000]

*****

응용 프로그램에서 커서를 사용할 수 밖에 없는 형편이라면 최고의 성능을 내기 위해서는 SQL Server의
tempdb 데이터베이스를 별도의 물리적인 디바이스에 위치시키도록 한다. 커서는 커서 데이터를 임시로 저장
하기 위해서 tempdb를 사용하기 때문이다. 디스크 어레이의 성능이 좋을 수록 커서의 속도도 빨라지게 된다.
[6.5, 7.0, 2000]

*****

커서를 사용하면 병행성(concurrency)이 떨어지기 때문에 불필요한 락킹(locking)과 블로킹(blocking)이 발생
할 소지가 있다. 이 문제를 해결하려면 가능한 READ_ONLY 커서를 사용하도록 하고 만약 수정 작업도 해야 한
다면 락킹을 줄이기 위해서 OPTIMISTIC 커서 옵션을 사용한다. 병행성(concurrency)을 저하시키는
SCROLL_LOCKS 커서 옵션의 사용은 피해야 한다. [6.5, 7.0, 2000]
(마이크로소프트의 추가 정보 : http://msdn.microsoft.com/library/default.asp?
URL=/library/psdk/sql/8_con_07_20.htm)

이 글은 스프링노트에서 작성되었습니다.

'Install /Setup' 카테고리의 다른 글

SQL 2012 Intergration Service 구성 항목 설정  (0) 2014.08.21
SQL 2008:: 삭제 레지스터리  (0) 2010.08.17
SQL Server 수동 시작  (1) 2010.01.22