반응형
반응형

sys.dm_io_virtual_file_stats 동적 관리 뷰는 데이터 로그 파일에 대한 I/O 통계 정보를 제공합니다. 사용자들이 어떤 파일에 대하여 읽기나 쓰기를 수행하기 위하여 기다린 시간을 제공하므로 뷰를 사용하면 어떤 파일들에 대하여 I/O 많이 발생하는지 확인할 있습니다. I/O 인한 성능 저하가 의심되는 경우에는 sys.dm_io_virtual_file_stats 뷰에서 io_stall 값을 점검할 것을 권고합니다.

 

[구문] sys.dm_io_virtual_file_stats(

{ database_id | NULL }

, { file_id | NULL }

)

 

데이터베이스 파일의 I/O 정보 확인하기

-- 모든 데이터베이스의 모든 파일들의 I/O 정보 확인

SELECT DB_NAME(database_id) as DBName,

       File_ID,

       File_Name(File_ID) as FileName,

       IO_Stall,

       Num_Of_Reads, Num_Of_Writes,

Num_Of_Bytes_Read, Num_Of_Bytes_Written

FROM sys.dm_io_virtual_file_stats (null, null)

ORDER BY IO_Stall DESC;

GO

-- 특정 데이터베이스의 모든 파일들에 대한 I/O 정보 확인 (: tempdb)

SELECT * FROM sys.dm_io_virtual_file_stats(DB_ID(‘tempdb’), null);

GO

-- 특정 데이터베이스의 특정 파일의 I/O 정보 확인 (: tempdb Primary Data File)

SELECT * FROM sys.dm_io_virtual_file_stats (DB_ID(‘tempdb’), 1);

GO

-- 특정 데이터베이스의 특정 파일의 I/O 정보 확인 (: tempdb 로그 파일)

SELECT * FROM sys.dm_io_virtual_file_stats (DB_ID(‘tempdb’), 2);

GO

 

 


모든 데이터베이스의 모든 파일들의 I/O 정보 확인하는 부분 중에 파일 이름 구하는 것에 약간의 오류가 있어서 쿼리 수정한것 댓글 답니다.

select DB_NAME(a.database_id) as DBName,
a.File_ID,
b.name,
a.IO_Stall,
a.Num_Of_Reads, a.Num_Of_Writes,
a.Num_Of_Bytes_Read, a.Num_Of_Bytes_Written
from sys.dm_io_virtual_file_stats(null, null) a
inner join sys.master_files b on a.database_id = b.database_id and a.file_id = b.file_id

반응형
반응형

카탈로그 뷰는 테이블, 인덱스 등과 같이 데이터베이스 엔진에서 사용하는 정보들을 조회할 있는 읽기 전용 뷰입니다. 카탈로그 뷰는 데이터베이스의 sys 스키마에 포함되어 있습니다. 또한 SQL Server 2005에서는 이전 버전에서 사용되었던 여러 시스템 테이블과의 호환성을 유지하기 위해 호환성 집합이 있습니다.

 

SQL Server 2000 시스템 테이블

SQL Server 2005 시스템

sysconfigures

sys.configurations

sysdevices

sys.backup_devices

syslockinfo,

sys.dm_tran_locks

syslocks

sys.dm_tran_locks

syslogins

sys.server_principals

sysperfinfo

sys.dm_os_performance_counters

sysprocesses

sys.dm_exec_connections

sys.dm_exec_sessions

sys.dm_exec_requests

sysservers

sys.servers

syscolumns

sys.columns

syscomments

sys.sql_modules

sysdepends

sys.sql_dependencies

sysfilegroups

sys.filegroups

sysfiles

sys.database_files

sysforeignkeys

sys.foreign_keys

sysindexes

sys.indexes

sysindexkeys

sys.index_columns

sysmembers

sys.database_role_members

sysobjects

sys.objects

sysreferences

sys.foreign_keys

systypes

sys.types

sysusers

sys.database_principals

 


반응형
반응형

sp_configure 사용하면 서버의 구성 옵션과 구성 옵션의 최소값과 최대값, 설정된 대상 , 설정값을 확인할 있습니다. 서버의 일부 옵션은 고급으로 지정되어 있으며 고급 옵션을 확인 또는 변경하려면 ‘show advanced options’ 옵션이 1이어야 합니다.

 

[구문] sp_configure [ [ @configname = ] 'name' ]

[ , [ @configvalue = ] 'value' ]

 

서버 구성 옵션 확인하기

EXEC sp_configure;

GO

-- 서버의 고급 구성 옵션 확인하기

EXEC sp_configure 'show advanced options', '1';

RECONFIGURE WITH OVERRIDE;

GO

EXEC sp_configure;

GO

 

sys.configurations 카탈로그 뷰를 조회하면 구성 옵션에 대한 정보를 자세하게 확인할 있습니다.

카탈로그 뷰를 이용하여 서버의 구성 옵션 확인하기

SELECT * FROM sys.configurations ORDER BY name;
GO

 

반응형
반응형

서버 인스턴스에 대한 속성 정보를 반환하는 SERVERPROPERTY 힘수를 사용합니다.

SERVERPROPERTY 함수의 ServerName 속성과 @@SERVERNAME 비슷한 정보를 반환하지만 결과가 다를 수도 있습니다. ServerName 속성은 Windows 서버 지정된 SQL Server 인스턴스에 대한 인스턴스 정보를 제공하고, @@SERVERNAME 현재 구성된 로컬 서버 이름을 제공합니다. 만일 기본 서버 이름을 변경하지 않았다면 ServerName 속성과 @@SERVERNAME 같은 정보를 반환합니다.

 

[구문] SERVERPROPERTY ( propertyname )

 

SQL Server 인스턴스 속성 정보 확인하기

SELECT SERVERPROPERTY('ServerName') AS ServerName

, SERVERPROPERTY('MachineName') AS MachineName

, SERVERPROPERTY('InstanceName') AS InstanceName

, SERVERPROPERTY('Edition') AS Edition

, SERVERPROPERTY('ProductVersion') AS ProductVersion

, SERVERPROPERTY('ProductLevel') AS ProductLevel;

GO

 

sp_dropserver, sp_addserver 저장 프로시저를 사용하여 로컬 서버 이름을 변경한 경우에는변경된 로컬 서버 이름 변경을 반환합니다.

SQL Server 실행하는 로컬 서버의 이름 확인하기

SELECT @@SERVERNAME;

GO

 

반응형
반응형
고정 데이터베이스 역할 목록입니다.


고정 데이터베이스 역할

데이터베이스 수준 사용 권한

서버 수준 사용 권한

db_accessadmin

허가된 사용 권한: ALTER ANY USER, CREATE SCHEMA

허가된 사용 권한: VIEW ANY DATABASE

db_accessadmin

GRANT 옵션을 사용하여 허가된 사용 권한: CONNECT

 

db_backupoperator

허가된 사용 권한: BACKUP DATABASE, BACKUP LOG, CHECKPOINT

허가된 사용 권한: VIEW ANY DATABASE

db_datareader

허가된 사용 권한: SELECT

허가된 사용 권한: VIEW ANY DATABASE

db_datawriter

허가된 사용 권한: DELETE, INSERT, UPDATE

허가된 사용 권한: VIEW ANY DATABASE

db_ddladmin

허가된 사용 권한: ALTER ANY ASSEMBLY, ALTER ANY ASYMMETRIC KEY, ALTER ANY CERTIFICATE, ALTER ANY CONTRACT, ALTER ANY DATABASE DDL TRIGGER, ALTER ANY DATABASE EVENT, NOTIFICATION, ALTER ANY DATASPACE, ALTER ANY FULLTEXT CATALOG, ALTER ANY MESSAGE TYPE, ALTER ANY REMOTE SERVICE BINDING, ALTER ANY ROUTE, ALTER ANY SCHEMA, ALTER ANY SERVICE, ALTER ANY SYMMETRIC KEY, CHECKPOINT, CREATE AGGREGATE, CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE QUEUE, CREATE RULE, CREATE SYNONYM, CREATE TABLE, CREATE TYPE, CREATE VIEW, CREATE XML SCHEMA COLLECTION, REFERENCES

허가된 사용 권한: VIEW ANY DATABASE

db_denydatareader

거부된 사용 권한: SELECT

허가된 사용 권한: VIEW ANY DATABASE

db_denydatawriter

거부된 사용 권한: DELETE, INSERT, UPDATE

 

db_owner

GRANT 옵션을 사용하여 허가된 사용 권한: CONTROL

허가된 사용 권한: VIEW ANY DATABASE

db_securityadmin

허가된 사용 권한: ALTER ANY APPLICATION ROLE, ALTER ANY ROLE, CREATE SCHEMA, VIEW DEFINITION

허가된 사용 권한: VIEW ANY DATABASE


반응형
반응형

고정 서버 역할 목록입니다

고정 서버 역할

서버 수준 사용 권한

bulkadmin

허가된 사용 권한: ADMINISTER BULK OPERATIONS

dbcreator

허가된 사용 권한: CREATE DATABASE

diskadmin

허가된 사용 권한: ALTER RESOURCES

processadmin

허가된 사용 권한: ALTER ANY CONNECTION, ALTER SERVER STATE

securityadmin

허가된 사용 권한: ALTER ANY LOGIN

serveradmin

허가된 사용 권한: ALTER ANY ENDPOINT, ALTER RESOURCES, ALTER SERVER STATE, ALTER SETTINGS, SHUTDOWN, VIEW SERVER STATE

setupadmin

허가된 사용 권한: ALTER ANY LINKED SERVER

sysadmin

GRANT 옵션을 사용하여 허가된 사용 권한: CONTROL SERVER

반응형
반응형

SQL Server에 로그인하면 기본적으로 연결되는 데이터베이스를 기본 데이터베이스라고 합니다. 기본 데이터베이스란 특정 로그인이 SQL Server에 로그인하면 자동으로 지정한 데이터베이스로 연결되도록 하는 것을 말합니다.

SQL Server 2000
에서는 최초에 로그인을 생성할 때 기본 데이터베이스를 지정할 수 있으며기본 데이터베이스를 변경하고자 하는 경우에는 sp_defaultdb를 사용하면 됩니다.

SQL Server 2005
에서도 최초에 로그인을 생성할 때 CREATE LOGIN 문에 DEFAULT_DATABASE = 데이터베이스명 절을 지정함으로써 기본 데이터베이스를 지정할 수 있습니다. 그리고 추후에 기본 데이터베이스를 변경하고자 하는 경우에는 ALTER LOGIN 문을 사용해야 합니다. sp_defaultdb는 다음 버전의 Microsoft SQL Server에서 제거될 예정이므로 대신 ALTER LOGIN을 사용하라는 권고 사항이 SQL Server 2005 온라인 설명서에 기술되어 있습니다.


:
ALTER LOGIN TestUser
WITH DEFAULT_DATABASE = TestDB;
GO

반응형
반응형

Windows Server 2003 이상의 운영체제에서 SQL Server 2005 운영하는 경우에는, SQL Server Windows 암호 정책을 사용할 있습니다.

- 로그인 생성 수정 CHECK_POLICY 옵션을 용하면, Windows 그룹 정책 사용 여부를 설정할 있습니다
.
- 로그인 생성 MUST_CHANGE 옵션을 사용하면, 사용자가 최초 로그인 시에 암호를 변경하도록 설정할 있습니다
.


암호 정책 변경하기 예제:

1. 관리 도구 --> 로컬 보안 정책(secpol.msc) 실행한 , 계정 정책 --> 암호 정책을 선택합니다.

2. 최소 암호 길이를 4문자로 설정합니다.

3.
만일 지정한 암호가 4 이하인 경우에는 다음과 같이 오류가 발생됩니다.

 


CREATE LOGIN dbadmin WITH PASSWORD = 'ad4';
GO
/*
메시지15116, 수준16, 상태1, 1
암호의 유효성을 검사하지 못했습니다. 암호가 너무 짧아서 Windows 정책요구사항에 맞지 않습니다.
*/


4.
만일 CHECK_POLICY = OFF 옵션을 이용하여 수행하면, 오류 없이 성공적으로 생성됩니다.

CREATE LOGIN dbadmin WITH PASSWORD = 'ad4', CHECK_POLICY = OFF;

GO


최초 로그인 암호를 변경하도록 설정하기 예제:

1. MUST_CHANGE
옵션을 이용하여 사용자가 최초 로그인 시 암호를 변경하도록 설정합니다.

CREATE LOGIN dbadmin WITH PASSWORD = 'adc1234' MUST_CHANGE, CHECK_EXPIRATION = ON;
GO

2. dbadmin으로 로그인 시 다음과 같은 메시지를 포함한 "암호 변경" 창이 나타납니다. 새 암호와 암호 확인 란에 새로운 암호를 입력해야 로그인이 가능하게 됩니다.

암호가 만료되었습니다. 로그온하려면 다른 암호를 입력해야 합니다.



암호의 복잡성 및 암호 만료:
Windows 2003 이상의 환경에서 암호 정책을 이용할 경우, 다음과 같은 기준의 암호 복잡성을 준수해야 합니다.

*   암호는 사용자 계정 이름의 일부 또는 전체를 포함할 없습니다.

*   암호의 길이는 최소 6 이상이어야 합니다.

*   암호는 다음 4가지 범주 범주의 문자를 포함해야 합니다.

-          알파벳 대문자 (A ~ Z)

-          알파벳 소문자 (a ~ z)

-          기본 숫자 10가지 (0 ~ 9)

-          영숫자가 아닌 문자( : !, $, #, %)

 

암호 만료 정책을 사용하면 특정 기간 경과 사용자에게 기존 암호를 변경할 것과 암호가 만료되어 계정을 사용할 없게 됨을 알려 주게 됩니다.

 

반응형
반응형

로그인 암호를 잊어 버려서 암호를 다시 설정해야 하는 경우가 종종 발생합니다.

SQL Server 2000에서는 sp_password라는 시스템 저장 프로시저를 사용하여 암호를 변경하셨을 겁니다. sp_password는 다음 버전의 Microsoft SQL Server에서 제거될 예정이므로 sp_passsword를 사용하는 응용 프로그램은 수정하고 sp_password 대신 ALTER LOGIN을 사용하라고 온라인 설명서에 나와 있습니다.

ALTER LOGIN
문을 사용하여 계정의 암호를 변경할 있습니다. 이전 암호를 알지 못하는 상태에서도 로그인의 암호를 변경하는 것이 가능합니다. 그렇지만 이전 암호를 알지 못하는상태에서 로그인의 암호를 변경하기 위해서는 사용자가 CONTROL SERVER 권한을 가지고 있어야 합니다. 권한을 가지고 있는 경우에는 OLD_PASSWORD 지정하지 않아도 암호를 변경할 있습니다.

로그인 계정 ‘dbadmin’ 암호를 ‘ad1234’ 에서 ‘ad5678’ 변경하기

ALTER LOGIN dbadmin WITH PASSWORD = ‘ad5678’ OLD_PASSWORD=’ad1234’;

GO

 

로그인 계정 ‘dbadmin’ 이전 암호를 모르는 상태에서 암호 변경하기

ALTER LOGIN dbadmin WITH PASSWORD = ‘ad5678’;

GO



[
중요] Windows Server 2003 에서 알려진 문제로 인해 LockoutThreshold 도달한 잘못된 암호 수를 다시 설정하지 못할 수도 있습니다. 경우 후속 로그인 시도가 실패하면 즉시 잠금이 발생할 있습니다. 간단하게 CHECK_POLICY = ON 앞에 CHECK_POLICY = OFF 설정하면 잘못된 암호 수를 수동으로 다시 설정할 있습니다

 

반응형
반응형

ALTER LOGIN 문을 사용하여 SQL Server 로그인 계정의 속성을 변경할 수 있습니다.

어떤 속성들을 변경할 수 있는지는 다음에 있는 구문을 참조하시면 쉽게 알 수 있습니다.

구문:
ALTER LOGIN login_name
    {
    <status_option>
    | WITH <set_option> [ ,... ]
    } <status_option> ::=
        ENABLE | DISABLE

<set_option> ::=           
    PASSWORD = 'password'
    [
            OLD_PASSWORD = 'oldpassword'
      | <secadmin_pwd_opt> [ <secadmin_pwd_opt> ]
    ]
    | DEFAULT_DATABASE = database
    | DEFAULT_LANGUAGE = language
    | NAME = login_name
    | CHECK_POLICY = { ON | OFF }
    | CHECK_EXPIRATION = { ON | OFF }
    | CREDENTIAL = credential_name
    | NO CREDENTIAL
  <secadmin_pwd_opt> ::=
    MUST_CHANGE | UNLOCK



ALTER LOGIN 문을 사용하여 다음과 같은 작업이 가능합니다.

1. 특정 로그인을 활성화 또는 비활성화할 수 있습니다.
일시적으로 로그인을 사용하지 못하도록 할 필요가 있을 때는 로그인을 삭제하는 대신 비활성화하는 방법을 사용하면 편리합니다.

예: TestUser 라는 로그인을 비활성화합니다.


ALTER LOGIN TestUser DISABLE;
GO
 

2. 로그인 암호를 변경할 수 있습니다. 암호 변경은 DBA가 반드시 알 필요가 있는 내용이므로 별도로 다루겠습니다.

예: TestUser 라는 로그인의 암호를 변경합니다.
 
ALTER LOGIN KittiLert WITH PASSWORD = '3948wJ698FFF7';
GO
 

3. 로그인 이름을 변경할 수 있습니다.

예 : TestUser 로그인의 이름을 NewUser로 변경합니다.

 
ALTER LOGIN TestUser WITH NAME = NewUser;
GO
 

4.  로그인으로 SQL Server에 연결했을 때 기본적으로 연결되는 디폴트 데이터베이스르 변경할 수 있습니다.

5. 잠긴 로그인을 잠금 해제하도록 변경할 수 있습니다.

6. MUST_CHANGE, CHECK_POLICY 또는 CHECK_EXPIRATION 옵션을 활성화 또는 비활성화할 수 있습니다.

7. 로그인을 자격 증명에 매핑할 수 있습니다.


반응형
반응형

T-SQL 문을 사용하여 SQL Server 로그인 계정을 생성하고, 생성한 계정의 기본 스키마를 지정하는 예제입니다.

로그인 사용자 생성하기

--dbadmin 로그인 계정을 생성합니다.
CREATE LOGIN dbadmin WITH PASSWORD = ‘ad1234’;

GO

-- dbadmin 로그인에 대한 사용자를 생성합니다.

-- 사용자의 기본 스키마는 MySchema 설정합니다. 이때 해당 스키마는 미리 생성하지 -- 않아도 됩니다.

CREATE USER UserA FOR LOGIN dbadmin

  WITH DEFAULT_SCHEMA = MySchema;

GO

-- MySchema 스키마를 생성하고 스키마의 소유권을 UserA 할당합니다.

CREATE SCHEMA MySchema AUTHORIZATION UserA;

GO

-- MySchema 내에서 Table1 테이블을 생성합니다.

CREATE TABLE MySchema.Table1 (seq int);

GO

 

 

로그인 확인하기

EXEC sp_helplogins;

GO

 

사용자 역할과 같은 보안 주체 확인하기

SELECT * FROM sys.database_principals;

GO

 

현재 서버에 존재하는 스키마 정보 확인하기

-- 스키마는 자신을 소유하는 보안주체의 아이디 (principal_id) 가지고 있습니다.

SELECT * FROM sys.schemas;

GO

 

반응형
반응형

로그인과 사용자

 

SQL Server 접근하기 위해서는 로그인 계정이 필요하고, 데이터베이스에 접근하기 위해서는 사용자(user) 필요합니다.

 

권한

 

사용자는 권한을 받아 작업을 수행할 있습니다. 권한에는 문장을 실행할 있는지에 따라 권한을 제한하는 명령문(Statement) 사용권한과 테이블, 색인, , 프로시저에 따라 권한을 제한하는 개체(Object) 사용권한이 있습니다.

 

역할

 

역할은 로그인 또는 사용자들의 집합이며 각각의 역할에는 권한이 설정되어 있습니다. 사용자에게 직접 권한을 주는 보다는 필요한 권한이 있는 역할에 사용자를 추가시키는 것이 좋습니다. 시스템에서 미리 정의된 역할에는 로그인이 사용할 있는 서버 역할과 사용자가 사용할 있는 데이터베이스 역할이 있습니다

 

보안 주체와 보안 개체

 

보안 주체는 데이터베이스 사용자, 데이터베이스 역할, 응용 프로그램 역할, SQL Server 로그인 Windows 로그인 등을 말합니다. 모든 보안 주체는 고유한 SID(고유 보안 식별자) 가지게 됩니다. 보안 개체는 테이블, , 프로시저와 같은 SQL 개체를 포함하는 스키마 개체 범위에 포함되는 구성 요소를 말합니다. 또한 스키마 사용자, 역할 등도 데이터베이스 범위에 포함이 되는 보안 개체이며, 데이터베이스, 로그인 등은 서버 범위에 포함이 되는 보안 개체입니다.
반응형
반응형

일반적으로 DBA가 통계를 수동으로 삭제하는 경우는 흔치 않습니다.

저는 컨설팅을 하면서 인덱스와 중복되는 통계의 삭제를 권고합니다.

대부분의 SQL Server 시스템들에서 인덱스와 중복되는 통계가 생성되고 업데이트되고 있습니다. 이미 인덱스로 인하여 관리되고 있는 통계를 불필요하게 중복으로 관리하는 것은 불필요한 오버헤드만 유발할 뿐이므로, 인덱스 튜닝을 수행하면서 중복 통계를 삭제토록 권유합니다.

통계 삭제는 DROP STATISICS 를 실행하면 됩니다.
반응형
반응형

많은 데이터의 추가, 변경 또는 삭제가 발생하여 인덱스의 키 값 분포가 크게 변경된 경우에는 해당 인덱스의 통계 갱신 즉, UPDATE STATISTICS를 실행하여 데이터베이스 엔진이 적절한 인덱스를 선택하도록 관리하는 작업이 필요합니다.
데이터베이스의 모든 사용자 정의 및 내부 테이블에 대해 UPDATE STATISTICS를 실행하기 위해서는 sp_updatestats를 실행합니다. sp_updatestats는 진행률을 나타내는 메시지를 표시하며, 업데이트가 완료되면 모든 테이블에 대해 통계가 업데이트되었다고 보고합니다. sp_updatestats는 비활성화된 비클러스터형 인덱스에 대한 통계를 업데이트하지만, 비활성화된 클러스터형 인덱스가 있는 테이블은 무시합니다.
명시적 또는 암시적 트랜잭션에서는 UPDATE STATISTICS가 허용되지 않습니다.
통계를 마지막으로 업데이트한 시기는 STATS_DATE 함수를 사용하여 확인 가능합니다

 

통계 업데이트하기

-- HumanResources.Employee 테이블의 모든 인덱스에 대한 통계 업데이트

USE AdventureWorks;

UPDATE STATISTICS HumanResources.Employee;

GO

-- HumanResources.Employee 테이블의 PK_Employee_EmployeeID 인덱스에 대한 통계 업데이트

USE AdventureWorks;

UPDATE STATISTICS HumanResources.Employee PK_Employee_EmployeeID;

GO

-- AdventureWorks 데이터베이스내의 모든 내부 테이블의 통계 업데이터

USE AdventureWorks;

EXEC sp_updatestats

GO

 

반응형
반응형

데이터베이스 옵션 중 IsAutoCreateStatistics 옵션이 활성화되어 있으면 필요한 경우 SQL Server가 자동으로 통계를 만듭니다.

통계는 인덱스가 없거나 인덱스의 첫 번째 키 열이 아닌 단일 컬럼에 대하여 생성하는 정보입니다. 예를 들어 (col1, col2, col3)에 하나의 복합 인덱스(Composite Index)가 만들어져 있다면 col2 또는 col3 에 통계를 만들어 주는 것을 고려할 수 있습니다. 이 때 인덱스의 첫 번째 키 열인 col1 에 대해서는 통계를 만들어 줄 필요가 없습니다. (col1, col2, col3)에 인덱스를 만들어 주면 인덱스의 첫 번째 컬럼인 col1에 대해서는 통계를 자동으로 관리하기 때문입니다.
 
CREATE STATISTICS 문을 사용하면 테이블이나 인덱싱된 뷰의 제공된 열 또는 열 집합에 관한 히스토그램 및 연관된 밀도 그룹(컬렉션)을 수동으로 만들 수 있습니다.

기본적으로 model 데이터베이스의 IsAutoCreateStatistics 옵션이 활성화되어 있으므로 관리자가 아무런 변경을 하지 않았다면 자동 통계 생성이 활성화되어 있을 겁니다.
자동 통계 생성이 활성화되어 있는 데이터베이스의 경우에는 수동으로 통게를 만들 필요는 거의 없습니다. 그러나 자동 통계 생성 옵션을 비활성화한 경우에는 성능 개선을 위하여 통게를 수동으로 만들어 줄 필요가 있을 수 있습니다.

반응형
반응형

앞에서 sys.dm_db_index_usage_stats 동적 관리 뷰에 대하여 설명하였습니다. sys.dm_db_index_usage_stats 동적 관리 뷰 외에 sys.dm_db_index_operational_stats 라는 동적 관리 함수가 있습니다.
sys.dm_db_index_operational_stats
현재 데이터베이스 또는 지정한 데이터베이스에 있는 테이블 또는 인덱스의 파티션별 I/O, 잠금, 래치 및 액세스 작업 방법에 대한 정보를 제공합니다.

sys.dm_db_index_operational_stats를 사용하여 사용자가 테이블, 인덱스 또는 파티션을 읽거나 쓰기 위해 대기해야 하는 시간을 추적하고 상당한 I/O 작업 또는 문제가 발생하고 있는 테이블이나 인덱스를 식별할 수 있습니다. 즉,
이러한 열을 사용하여 경합이 발생하고 있는 영역을 식별할 수 있습니다.

 

 

[구문] sys.dm_db_index_operational_stats (

    { database_id | NULL }

    , { object_id | NULL }

    , { index_id | NULL | 0 }

    , { partition_number | NULL }

)

 

Adventureworks 데이터베이스내의 모든 인덱스에 대한 정보 확인하기

SELECT *

FROM sys.dm_db_index_operational_stats(db_id('adventureworks'),null,null,null);

GO

 

SQL Server 인스턴스 내의 모든 테이블 및 인덱스에 대한 정보 확인하기

SELECT * FROM sys.dm_db_index_operational_stats(NULL, NULL, NULL, NULL);
GO

 

 

AdventureWorks 데이터베이스에 있는 특정 테이블에 대한 정보 반환하기

SET @db_id = DB_ID(N'AdventureWorks');
SET @object_id = OBJECT_ID(N'AdventureWorks.Person.Address');
SELECT * FROM sys.dm_db_index_operational_stats(@db_id, @object_id, NULL, NULL);
GO

 

반응형
반응형

실제 많은 수의 운영 환경들에서 테이블에 만들어져 있는 인덱스들의 일부는 실제로는 사용되지 않는 인덱스입니다. 실제로 사용되지 않는 인덱스를 관리하는 것은 불필요한 오버헤드만 유발하므로 인덱스 사용여부를 확인하고 실제로 사용되지 않는 불필요한 인덱스들을 구분해 내고 삭제하는 것이 필요합니다.
SQL Server 2005에서 새롭게 제공되는 DMV 중에서 sys.dm_db_index_usage_stats
동적 관리 뷰를 사용하여 사용된 인덱스와 빈도를 있습니다. 뷰를 사용하여 응용 프로그램에서 사용하지 않는 인덱스를 확인할 있으며, 또한 유지 관리 오버헤드를 유발하는 인덱스를 확인할 수도 있습니다.

SQL Server 서비스를 시작할 때마다 카운터는 상태로 초기화되며, 데이터베이스가 분리되거나 종료될 때마다(: AUTO_CLOSE ON으로 설정된 경우) 데이터베이스와 관련된 모든 행이 제거됩니다. 그러므로 DMV에 대한 스냅샷을 영구 테이블에 복사해 둠으로써 SQL Server가 재시작되기 이전의 데이터도 관리하는 것을 권고합니다.

 

다음에 sys.dm_db_index_usage_stats 동적 관리 뷰를 활용한 예제 스크립트가 있습니다. DMV를 활용한 스크립트는 아래 예제 스크립트 외에도 다양하게 작성될 수 있습니다.

Adventureworks 데이터베이스 인덱스 사용현황 확인하기

SELECT * FROM sys.dm_db_index_usage_stats

WHERE database_id = db_id('Adventureworks');

GO

 

사용되지 않은 인덱스 확인하기

SELECT object_name(i.object_id) AS Table_Name, i.name AS Index_Name

FROM sys.indexes i, sys.objects o

WHERE  i.index_id NOT IN

             (SELECT s.index_id

              FROM sys.dm_db_index_usage_stats s

              WHERE s.object_id=i.object_id and

                                       i.index_id=s.index_id and

                                        database_id = db_id() )  -- dbid : db_id() 값을 입력

AND o.type = 'U'

AND o.object_id = i.object_id

ORDER BY object_name(i.object_id) ASC

GO


[주의] 인덱스가 사용되지 않는 인덱스라고 확인되더라도 충분히 오랜 기간 동안 모니터링하지 않았다면 섣불리 인덱스를 삭제해도 무방하다고 판단해서는 안됩니다. 만일 크기가 큰 테이블에 대해서 어떤 응용 프로그램에서 사용하는 인덱스를 실수로 삭제하게 되면 심각한 블로킹과 성능 저하가 발생할 수 있습니다.

반응형
반응형

불필요한 인덱스를 삭제하지 않고 그대로 두면 오버헤드만 유발하므로, 인덱스가 불필요하다고 판단되면 삭제하는 것이 바람직합니다.

인덱스를 삭제하고자 하는 경우에는 DROP INDEX를 사용하면 됩니다.
DROP INDEX 구문도 SQL Server 2005에서 변경되었으므로 DROP INDEX를 사용하기 전에 SQL Server 2005 온라인 설명서에서 DROP INDEX 구문을 살펴 보시기 바랍니다.

이전 버전과의 호환성을 위해 SQL Server 2000의 구문이 지원되기는 하지만 이후 버전에서는 제거될 수 있으므로 SQL Server 2005 구문에 맞게 작성 또는 수정하실 것을 권고합니다.

-- SQL Server 2000 구문

DROP INDEX Employee.IX_Employee_ManagerID;

GO

-- SQL Server 2005 구문
DROP INDEX IX_Employee_ManagerID ON Employee;

GO

인덱스 관련 T-SQL 문 중에 ALTER INDEX 문이 있는데, ALTER INDEX로는 인덱스를 구성하는 열을 변경하거나 파일 그룹을 변경할 없습니다. 인덱스를 구성하는 열을 추가 또는 삭제, 순서를 변경하거나 인덱스가 저장된 파일 그룹을 변경하고자 하는 경우에는 인덱스를 삭제한 다시 생성해야 합니다.

 
만일 PRIMARY KEY 제약 조건이나 UNIQUE 제약 조건을 정의함으로써 생성된 인덱스는 DROP INDEX로 삭제할 수 없습니다.
이러한 제약 조건들은 ALTER TABLE 문의 DROP CONSTRAINT 절을 사용하여 삭제합니다.

반응형
반응형

인덱스 비활성화는 사용자가 인덱스를 사용할 없도록 하며, 제약 조건을 포함한 모든 인덱스에 사용 가능합니다. , 비활성화된 인덱스는 유지 관리 되지 않고, 쿼리 옵티마이저에 의해 고려 되지도 않습니다. 비클러스터형 인덱스 또는 클러스터형 인덱스를 비활성화하면 인덱스의 메타 데이터는 시스템 카탈로그에 남기지만, 물리적으로 인덱스 데이터를 삭제합니다. 그러므로, 비활성화된 인덱스와 동일한 이름으로 인덱스를 생성할 없습니다. 클러스터형 인덱스의 경우는 비활성화하면 데이터는 삭제되지 않고 남아 있지만, 해당 테이블의 데이터에 접근할 없어, 데이터의 수정은 물론 조회도 불가능합니다.

인덱스의 비활성화 여부는 sys.indexes 카탈로그 뷰의 is_disabled 열을 확인합니다. 인덱스의 비활성화는 ALTER INDEX DISABLE 사용하고, 비활성화된 인덱스를 다시 활성화 시키기 위해서는 ALTER INDEX REBUILD 또는 CREATE INDEX WITH DROP_EXISTING 구문을 사용합니다. 비활성화된 클러스터형 인덱스를 재작성할 때에는 ONLINE 옵션을 ON으로 설정할 없으며, 비활성화된 비클러스터형 인덱스를 재작성할 때에는 ONLINE 옵션을 ON으로 설정할 있습니다.

 

비클러스터형 인덱스 비활성화한 , 다시 활성화하기

USE AdventureWorks;

GO

-- 비클러스터형 인덱스 비활성화

ALTER INDEX IX_Employee_ManagerID ON HumanResources.Employee

DISABLE ;

GO

-- 비활성화된 인덱스 확인

SELECT is_disabled FROM sys.indexes

WHERE object_id=object_id('HumanResources.Employee')

AND name='IX_Employee_ManagerID';

/* 1 */

-- 온라인으로 인덱스 재작성

ALTER INDEX IX_Employee_ManagerID ON HumanResources.Employee

REBUILD WITH (ONLINE=ON);

GO

-- 재작성된 인덱스의 비활성화 여부 확인

SELECT is_disabled FROM sys.indexes

WHERE object_id=object_id('HumanResources.Employee')

AND name='IX_Employee_ManagerID';

GO

 

클러스터형 인덱스 비활성화한 , 다시 활성화하기

USE AdventureWorks;

GO

ALTER INDEX PK_Employee_EmployeeID ON HumanResources.Employee

DISABLE ;

GO

SELECT * FROM HumanResources.Employee;

GO

/*

메시지 8655, 수준 16, 상태 1, 1

테이블 또는 Employee' 인덱스 'PK_Employee_EmployeeID'() 비활성화되었으므로 쿼리 프로세서에서 계획을 생성할 없습니다.

*/

ALTER INDEX ALL ON HumanResources.Employee

REBUILD;

GO

 

 

FOREIGN KEY 제약 조건이 있는 클러스터형 인덱스 비활성화한 , 활성화하기

USE Sample;

GO

-- 테스트 테이블 생성

CREATE TABLE STATES (STATE CHAR(2) NOT NULL);

GO

CREATE TABLE CITIES (

                            CITY VARCHAR(30) NOT NULL,

                            STATE CHAR(2) ,

                  ZIP INT);

GO

-- PK 제약 조건과 FK 제약 조건 생성

ALTER TABLE STATES

ADD CONSTRAINT PK_STATES PRIMARY KEY CLUSTERED (STATE);

GO

ALTER TABLE CITIES

ADD CONSTRAINT PK_CITIES PRIMARY KEY CLUSTERED (CITY);

GO

ALTER TABLE CITIES

ADD CONSTRAINT FK_CITIES_STATES_STATE FOREIGN KEY (STATE)

REFERENCES STATES (STATE);

GO

 

-- CITIES 테이블에 데이터 INSERT

-- STATES 테이블에 없는 PR 값은 CITIES INSERT 없다

INSERT INTO STATES SELECT 'CA';

GO

INSERT INTO CITIES SELECT 'Los Angles', 'CA',111;

GO

INSERT INTO CITIES SELECT 'San Juan', 'PR' ,222;

GO

/*

메시지 547, 수준 16, 상태 0, 1

INSERT 문이 FOREIGN KEY 제약 조건 "FK_CITIES_STATES_STATE"() 충돌했습니다. 데이터베이스 "sample", 테이블 "dbo.STATES", column 'STATE'에서 충돌이 발생했습니다.

문이 종료되었습니다.

*/

 

-- STATES 테이블의 클러스터형 인덱스 비활성화

-- FOREIGN KEY 제약 조건도 동시에 비활성화된다

ALTER INDEX PK_STATES ON STATES

DISABLE;

GO

/*

경고: 인덱스 'PK_STATES'() 비활성화한 결과 테이블 'STATES'() 참조하는 테이블 'CITIES' 외래 'FK_CITIES_STATES_STATE'() 비활성화되었습니다.

*/

 

-- CITIES 테이블에 데이터 INSERT

-- (FOREIGN KEY 제약 조건이 비활성화되었으므로 STATES 테이블에 없는 PR 값을 INSERT 있다)

INSERT INTO CITIES SELECT 'San Juan', 'PR' ,222;

GO

 

-- STATES 테이블의 클러스터형 인덱스 재작성

ALTER INDEX PK_STATES ON STATES

REBUILD;

GO

-- CITIES 테이블에 데이터 INSERT

-- (FOREIGN KEY 제약 조건은 여전히 비활성화 상태이므로 STATES 테이블에 없는 PR 값을 INSERT 있다)

INSERT INTO CITIES SELECT 'Detroit', 'PR' ,333;

GO

 

-- FOREIGN KEY 제약 조건 재생성하기

ALTER TABLE  CITIES

CHECK CONSTRAINT FK_CITIES_STATES_STATE;

-- CITIES 테이블에 데이터 INSERT

-- (FOREIGN KEY 제약 조건이 재생성되었으므로 STATES 테이블에 없는 PR 값을 INSERT 없다)

INSERT INTO CITIES SELECT 'Kenmore', 'PR' ,444;

GO

/*

메시지 547, 수준 16, 상태 0, 1

INSERT 문이 FOREIGN KEY 제약 조건 "FK_CITIES_STATES_STATE"() 충돌했습니다. 데이터베이스 "sample", 테이블 "dbo.STATES", column 'STATE'에서 충돌이 발생했습니다.

문이 종료되었습니다.

*/

 

 

[참고]

PRIMARY KEY 제약 조건을 FOREIGN KEY 제약 조건이 참조하고 있는 경우, 인덱스가 비활성화되면 FOREIGN KEY 제약 조건도 동시에 비활성화됩니다. 그러나, PRIMARY KEY 제약 조건을 재구성했다고 하더라도 FOREIGN KEY 제약 조건은 재구성되지 않으므로, PRIMARY KEY 제약 조건을 재구성한 수동으로 FOREIGN KEY 제약 조건을 재생성해야 합니다.

반응형
반응형

SQL Server 2005에서 인덱스와 관련하여 개선된 기능 중 하나인 온라인 인덱스 작업에 대하여 알아 보겠습니다. 온라인 인덱스 작업의 지원은 1년365일, 24시간 운영되어야 하는 시스템을 관리하는 DBA들이 학수고대하던 기능입니다. 온라인 인덱스 작업의 지원으로 인하여 인덱스 작업으로 인한 다운타임이 감소하고 인덱스를 재구성하고 싶어도 소요시간 때문에 인덱스 재구성 작업을 엄두도 내지 못하던 대용량 시스템에 도움이 될 것으로 생각됩니다.

SQL Server 2005에서는 온라인으로 인덱스를 만들고 다시 작성하고 삭제할 수 있게 되었습니다. ONLINE 옵션을 사용하면 인덱스 작업이 수행되는 동안 기본 테이블(BASE TABLE)이나 클러스터형 인덱스 데이터를 쿼리하고 업데이트할 수 있게 되었습니다.

ONLINE 옵션은 다음과 같은 Transact-SQL 문에서 사용할 수 있습니다.
- CREATE INDEX
- ALTER INDEX
- DROP INDEX
- ALTER TABLE (CLUSTERED 인덱스 옵션을 사용하는 UNIQUE 제약 조건이나 PRIMARY KEY 제약 조건을 추가하거나 삭제하는 경우)


참고로, 인덱스를 다시 구성하는 작업은 항상 온라인으로 수행됩니다만, 인덱스를 다시 작성하는 작업은 기본적으로 오프라인으로 수행됩니다. 인덱스를 다시 작성할 때에도 ONLINE
옵션을 ON으로 설정하면 변경 중에 아주 잠시 동안만 배타 테이블 잠금이 유지되기 때문에 인덱스 작성 중에도 데이터의 조회와 수정 가능하게 됩니다.


온라인
인덱스 작업은 SQL Server 2005 Enterprise Edition에서만 가능합니다.

반응형
반응형

앞에서 인덱스 조각화 확인 방법을 소개하였으므로, 이제는 인덱스 조각화를 제거하는 방법을 설명하겠습니다. 인덱스 조각화를 제거하는 방법에는 여러 가지가 있습니다. 인덱스를 재구성하거나 인덱스를 재작성하거나 인덱스를 삭제하고 다시 만드는 등의 여러 가지 방법이 가능합니다. SQL Server 2005에서 인덱스 조각화 제거 구문에 변경이 발생하였으므로, 이미 아시는 내용이겠지만 기본적인 내용을 살펴 보겠습니다.  

인덱스 다시 구성

 

ALTER INDEX 문에 REORGANIZE 절을 사용하면 인덱스를 다시 구성할 있습니다. SQL Server 2000에서의 DBCC INDEXDEFRAG 대신 기능을 사용하는 것을 권고합니다.

인덱스를 다시 구성하면 리프 노드의 논리적 순서(왼쪽에서 오른쪽으로) 일치하도록 리프 수준 페이지가 다시 정렬되어 테이블과 뷰의 클러스터형 비클러스터형 인덱스의 리프 수준이 조각 모음됩니다. 클러스터형 인덱스를 다시 구성하면 클러스터형 인덱스의 리프 수준에 포함된 모든 LOB 열이 압축됩니다. 비클러스터형 인덱스를 다시 구성하면 인덱스 내의 포괄 열인 모든 LOB 열이 압축됩니다.

sys.indexes 카탈로그 뷰의 채우기 비율 값을 기준으로 인덱스의 페이지를 압축하고, 압축으로 인해 생성된 페이지는 제거됩니다. 재구성은 온라인으로 수행되며, 차단 잠금을 오래 보유하지 않으므로 쿼리나 업데이트의 실행을 차단하지 않습니다.

인덱스가 심하게 조각화되지 않은 경우에는 인덱스를 재구성하면 되지만, 인덱스가 심하게 조각화된 경우에는 인덱스를 재작성하는 것이 좋습니다..

 

인덱스 재구성하기

USE AdventureWorks;

GO

ALTER INDEX PK_ProductPhoto_ProductPhotoID ON Production.ProductPhoto

REORGANIZE ;

GO

 

 

인덱스 다시 작성

 

인덱스 조각화로 인한 성능 저하를 방지하기 위해서는 주기적으로 인덱스 조각화가 진행된 테이블들에 대한 조각화 제거 작업이 필요합니다. 조각화를 제거하기 위한 작업 중의 하나가 인덱스를 다시 작성하는 것입니다. 인덱스 재작성은 인덱스를 삭제한 다시 생성하는 작업으로, 인덱스를 논리적 정렬과 일치하도록 물리적으로 재정렬합니다. 인덱스가 만들어졌을 지정된 FILLFACTOR 계산하여 인덱스의 페이지를 압축하여, 디스크 공간을 확보하고 필요한 만큼 페이지를 할당하여 인덱스 행을 연속되는 페이지에 다시 정렬합니다. 작업은 ALTER INDEX REBUILD 절을 사용하여 있으며, DBCC DBREINDEX 대신 기능을 사용하는 것을 권고합니다. 또한, CREATE INDEX DROP_EXISTING 절을 사용하여 인덱스 재작성 작업을 수도 있습니다. 작업을 통하여, 요청한 데이터를 얻는 필요한 페이지 읽기 횟수를 줄일 있으므로 디스크 성능이 향상됩니다.  ALL 명시하면 하나의 트랜잭션으로 테이블의 모든 인덱스를 제거하고 다시 작성합니다. SQL Server 2005에서는 비클러스터형 인덱스를 온라인으로 재작성할 있습니다.

가능한 인덱스 재작성 작업을 자동화하여 주기적으로 용이하게 수행할 있는 체계를 갖출 것을 권고합니다.

 

비클러스터형 인덱스를 온라인 모드로 재작성하기

ALTER INDEX IX_Employee_ManagerID ON HumanResources.Employee

REBUILD WITH (ONLINE=ON);

GO

 

반응형
반응형

인덱스는 검색의 속도를 빠르게 해 주는 매우 유용한 기능입니다. 초보 DBA들의 경우에는 인덱스는 한번 만들어 두기만 하면 되는 것으로 알고, 인덱스에 대한 관리를 전혀 하지 않는 경우들이 흔히 있습니다. 수년동안 사용해 오면서 재구성 작업을 한번도 실행해 주지 않아서 인덱스 조각화가 매우 심해진 경우들도 심심찮게 볼 수 있습니다. 인덱스 조각화가 매우 심한 경우에 인덱스 재구성만으로도 성능이 개선되는 효과를 얻기도 합니다. 이와 같이 인덱스는 주기적인 관리가 필요한데, 그런 관리를 위해서는 인덱스의 조각화가 어느 정도 진행되었는지를 확인하는 방법을 알고 있어야 합니다. 그래서 오늘은 먼저 인덱스 조각화를 확인하는 방법에 대하여 소개해 보겠습니다. 


테이블에 INSERT, UPDATE, DELETE가 발생함에 따라서 조각화가 발생하게 됩니다.
조각화가 발생하면 원하는 데이터를 가져오기 위하여 읽어야 페이지 수가 늘어나, 성능에 좋지 않은 영향을 미칠 있으므로 주기적으로 조각화를 제거하는 작업이 필요합니다. 인덱스 관리에 대하여 알고 있는 DBA들은 주기적으로 인덱스 조각화 제거를 위한 인덱스 재구성 작업을 실행해 줍니다. 그런데 대부분의 경우에 특정 데이터베이스 내의 모든 사용자 테이블들의 모든 인덱스들에 대하여 한번에 인덱스 재구성을 수행하는 것이 일반적입니다. 시스템 오픈 초기에는 데이터의 크기가 작아서 속편하게 한달에 한번 또는 일주일에 한번 야간에 인덱스 재구성을 수행하여도 문제가 없었는데, 데이터의 크기가 점점 커져서 어느 날에는 야간 업무 휴지 시간동안 인덱스 재구성 작업이 완료되지 않아서 정상적인 서비스를 제공하지 못하는 장애가 발생하는 경우도 가끔 볼 수 있습니다.
인덱스 조각화 정도는 인덱스에 따라 천차만별인데 무조건 일률적으로 인덱스 조각화 제거 주기를 적용하는 것은 비효율적이라고 생각합니다. 그러므로 먼저 인덱스 별로 인덱스 조각화 상태를 모니터링하고, 인덱스 별로 인덱스 재구성 스케줄을 적절하게 구성하는 것을 권고합니다. 그리고 향후 소요시간이 증가할 경우를 대비하여 인덱스 별로 날짜를 분산하여 인덱스 재구성을 실행할 것을 권고합니다.


그러면 이제 본론으로 들어 가서 인덱스 조각화를 확인하는 방법을 설명하겠습니다. 

조각화 정보를 알기 위하여 이전 버전에서 사용했던 DBCC SHOWCONTIG 사용이 가능하지만, SQL Server 2005에서는 테이블의 조각화 정보를 sys.dm_db_index_physical_stats 동적 관린 뷰를 사용하여 확인할 있습니다.

 

[구문]

sys.dm_db_index_physical_stats (

    { database_id | NULL }               /* NULL: 서버내의 모든 데이터베이스 */

    , { object_id | NULL }                /* NULL: 해당 데이터베이스내의 모든 오브젝트 */

    , { index_id | NULL | 0 }              /* NULL: 해당 테이블의 모든 인덱스 */

    , { partition_number | NULL } /* NULL: 해당 오브젝트의 모든 인덱스 */

    , { mode | NULL | DEFAULT } /* NULL: LIMIT */

)

mode에는 DEFAULT, NULL, LIMITED, SAMPLED, DETAILED 입력할 있으며, DEFAULT 또는 NULL LIMITED 의미합니다.

LIMITED 모드는 가장 빠르고 가장 적은 페이지를 스캔합니다. , 힙의 모든 페이지와 인덱스의 레벨을 제외한 페이지를 스캔합니다.

SAMPLED 모드는 인덱스 또는 힙의 모든 페이지중에서 1% 샘플에 대한 통계를 반환합니다. 만일, 인덱스 또는 힙이 10,000 페이지보다 적다면 SAMPLED 대신에 DETAILED 모드가 사용됩니다.

DETAILED 모드는 모든 페이지를 스캔하고 모든 통계를 반환합니다.


조각화는 다음과 같은 스크립트를 활용하여 확인 가능합니다.

DECLARE @db_id SMALLINT;

DECLARE @object_id INT;

 

SET @db_id = DB_ID(N'AdventureWorks');

SET @object_id = OBJECT_ID(N'AdventureWorks.Person.Address');

 

IF @db_id IS NULL

BEGIN;

    PRINT N'Invalid database';

END;

ELSE IF @object_id IS NULL

BEGIN;

    PRINT N'Invalid object';

END;

ELSE

BEGIN;

    SELECT * FROM sys.dm_db_index_physical_stats(@db_id, @object_id, NULL, NULL , 'LIMITED');

END;

GO
반응형
반응형

인덱스 옵션 중에 IGNORE_DUP_KEY 라는 옵션이 있습니다. 이 옵션은 기본 모드가 중복 무시인 이기종 DBMS에서 SQL Server 2005로 마이그레이션하는 경우에 유용하게 사용할 수 있는 옵션이므로, 여러분에게 소개 드리고자 합니다.

IGONORE_DUP_KEY
옵션을 활성화하면 다중 INSERT 작업 중복 값이 들어올 오류가 아닌 경고 메시지를 반환하고 고유 인덱스에 위배되는 행만 INSERT에서 제외됩니다. 다른 문제만 없다면 고유 인덱스에 위배되지 않는 나머지 행들은 성공적으로 INSERT가 이루어집니다.
 
IGNORE_DUP_KEY 옵션을 비활성화한 상태에서는 고유 인덱스에 위배되는 행이 존재하면 오류 메시지가 반환되며 전체 INSERT 트랜잭션이 롤백됩니다.

참고로, 인덱스 옵션은 WITH 절을 사용하여 기술하며 SQL Server 2005의 구문은 SQL Server 2000의 구문과 조금 달라졌습니다. SQL Server 2005에서 새롭게 지원되는 인덱스 옵션은 WITH (option_name = ON}OFF) 을 사용해야만 지정할 수 있습니다. 설사 SQL Server 2000과 호환되는 옵션이더라도 새롭게 스크립트를 작성하거나 기존 스크립트를 수정하는 경우에는 SQL Server 2005의 구문을 준수하여 작성할 것을 권고합니다.

- SQL Server 2000 : WITH <index_option>
- SQL Server 2005 : WITH <index_option = ON | OFF>


다음에 IGNORE_DUP_KEY 옵션을 사용한 예제가 있습니다. 한번 따라해 보시면 쉽게 이해가 되실 겁니다.

-- 1. 테스트 테이블을 만듭니다.

CREATE TABLE #Test (C1 nvarchar(10), C2 nvarchar(50), C3 datetime);

GO

-- 2. 테스트 테이블에 IGNORE_DUP_KEY 옵션이 활성화된 인덱스를 생성합니다.

CREATE UNIQUE INDEX AK_Index ON #Test (C2)

    WITH (IGNORE_DUP_KEY = ON);

GO


-- 3. 하나의 일괄 처리(Batch) 안에서 Adventureworks.Production.UnitMeasure 테이블에 존재하는 행과 동일한 값을 가지는 한 행을 미리 INSERT 하고 Adventureworks.Production.UnitMeasure 테이블의 전체 데이터를 복사함으로써 중복  INSERT를 발생시킵니다. 오류 대신 경고 메시지가 반환되며 정상적으로 처리되는 것을 확인할 수 있습니다.
INSERT INTO #Test VALUES (N'OC', N'Ounces', GETDATE());

INSERT INTO #Test

SELECT * FROM Adventureworks.Production.UnitMeasure;

GO

/*

중복 키가 무시되었습니다.

*/

-- 클린업
DROP TABLE #Test;

GO

반응형
반응형

SQL Server 2005에는 키가 아닌 열을 포함한 비클러스터형 인덱스를 생성할 수가 있습니다. 키가 아닌 열을 포함한 인덱스, 포괄 열이 있는 인덱스는 인덱스 커버링 가능성을 높여 주기 때문에 쿼리의 성능을 개선시키는데 도움이 됩니다.
참고로 인덱스 커버링이랑
쿼리 옵티마이저가 테이블 데이터나 클러스터형 인덱스의 데이터를 참조하지 않고 비클러스터형 인덱스의 값만을 참조하여 원하는 데이터를 얻는 것을 말합니다. 이와 같이 데이터나 클러스터형 인덱스를 참조하지 않게 되면 적은 I/O로 원하는 결과를 얻게 되므로 성능적인 측면에서 도움이 됩니다.

포괄 열이 있는 인덱스는 다음과 같은 장점이 있습니다.

 

?         인덱스 열로 허용되지 않는 데이터 형식을 포괄 열에는 포함시킬 수 있습니다. 포괄 열 인덱스에는 text, ntext, image 데이터 형식을 제외한 모든 데이터 형식이 허용됩니다.

?         비클러스터형 인덱스를 구성하는 인덱스 열의 개수 또는 인덱스 키의 크기의 계산에서 제외됩니다.


다음 예제에서와 같이 CREATE INDEX 문에 INCLUDE 절을 추가하여 포괄 열 인덱스를 생성할 수 있습니다. 

[따라하기] 포괄 열을 추가한 인덱스 생성하기

USE AdventureWorks;

GO

-- 포괄 열을 추가한 인덱스 생성

CREATE NONCLUSTERED INDEX IX_Address_PostalCode

    ON Person.Address (PostalCode)

    INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);

GO

-- 포괄 인덱스로 인해 성능이 향상되는 쿼리

SELECT AddressLine1, AddressLine2, City, StateProvinceID, PostalCode

FROM Person.Address

WHERE PostalCode BETWEEN N'98000' and N'99999';

GO

 

반응형
반응형

인덱스는 테이블이나 뷰의 조회를 빠르게 하기 위한 데이터 구조입니다. 인덱스는 테이블이나 뷰의 또는 이상의 열로 구성되어 있는 키로 구성되어 있으며, 키는 B-트리 구조로 구성되어 있습니다. 인덱스는 조회의 속도는 증가 시키지만, INSERT 속도는 저하시키므로 적절한 인덱스를 생성하는 것이 중요합니다. 인덱스는 테이블, , 또는 테이블의 XML 인덱스에 생성할 있습니다.

 

인덱스의 종류

 

n       클러스터형 인덱스

클러스터형 인덱스를 구성하는 값의 순서에 의해 테이블 또는 뷰의 데이터가 물리적으로 정렬되어 있습니다. 그러므로, 클러스터형 인덱스는 테이블에 개만이 존재할 있습니다. 클러스터형 인덱스가 존재하여 클러스터형 인덱스의 값에 따라 데이터가 정렬되어 있는 테이블을 클러스터형 테이블이라고 하고, 클러스터형 인덱스가 없는 테이블을 이라고 합니다.

 

클러스터형 인덱스는 다음과 같은 선정 조건을 가지는 것이 좋습니다.

 

?         고유한 값을 가지는 열로 생성하는 것이 좋습니다. 중복값이 존재하는 경우에는 시스템 내부에서 고유한 값을 가지기 위하여 “uniqifier” 추가되기 때문에 추가적인 오버 헤드가 발생합니다.

?         인덱스 길이는 짧은 것이 좋습니다. 클러스터형 인덱스가 길어지면 비클러스터형 인덱스의 길이도 길어지기 때문에 인덱스 크기가 커집니다.

?         정적인 열에 생성하는 것이 좋습니다. 자주 변경되는 열에 클러스터형 인덱스를 생성하면 키에 대한 업데이트 작업에 대한 비용이 증가합니다.

 

[따라하기] 클러스터형 인덱스 생성하기

CREATE TABLE TestTable (a int, b int, c AS a/b);

GO

CREATE CLUSTERED INDEX IDX_c ON TestTable (c);

GO

 

n       비클러스터형 인덱스

비클러스터형 인덱스는 데이터와 분리된 데이터 구조를 가집니다. 비클러스터형 인덱스는 비클러스터형 인덱스 값을 포함하며, 값에 해당하는 데이터 열이 위치한 포인터 로케이터 가집니다. 클러스터형 인덱스를 가지고 테이블의 비클러스터형 인덱스의 경우에 로케이터는 클러스터형 인덱스 키이고, 클러스터형 인덱스가 없는 테이블의 경우에는 로케이터는 열의 위치를 나타내는 RID입니다.
반응형
반응형

테이블이 사용하는 디스크 공간에 대한 정보를 확인할 필요가 있는 경우가 종종 발생합니다. sp_spaceused 를 실행하면 행의 수와 예약된 공간, 데이터 크기와 인덱스 크기를 확인할 수 있습니다.

특정 데이터베이스에 존재하는 모든 사용자 테이블들의 공간 정보를 모니터링할 필요가 있는 경우에는 다음과 같은 방법을 사용하면 작업이 용이합니다.

/* 방법1. 기존의 시스템 SP 단순히 활용한 예제 */

EXEC sp_MSforeachtable 'EXEC sp_spaceused [?], ''TRUE''';

GO


/* 방법2. 기존의 시스템 SP 활용하여 결과를 테이블에 저장한 예제 */

USE Sample;

GO

CREATE TABLE spaceused_AdventureWorks (

             TableName           sysname,

             Rows                   int,

             Reserved             varchar(20),

             Data                    varchar(20),

             Index_size           varchar(20),

             Unused                varchar(20));

GO

USE AdventureWorks;

GO

INSERT INTO Sample.dbo.spaceused_AdventureWorks

EXEC sp_MSforeachtable 'EXEC sp_spaceused [?], ''TRUE''';

GO

SELECT * FROM Sample.dbo.spaceused_AdventureWorks;

GO



/* 방법3. sp_spaceused 소스 코드를 수정하여 사용하기 */

CREATE PROCEDURE sys.sp_spaceused_alltable

AS

SET NOCOUNT OFF

SELECT t1.tablename,

rows = convert(char(11),t1.rows),

reserved = ltrim(str((t1.reservedpages+isnull(t2.reservedpages,0)) * 8192 / 1024.,15,0) + ' KB'),

data = ltrim(str(t1.pages * 8192 / 1024.,15,0) + ' KB'),

index_size = ltrim(str(((t1.usedpages+isnull(t2.usedpages,0)) - t1.pages) * 8192 / 1024.,15,0) + ' KB'),

unused = ltrim(str(((t1.reservedpages+isnull(t2.reservedpages,0)) - (t1.usedpages+isnull(t2.usedpages,0))) * 8192 / 1024.,15,0) + ' KB')

FROM (

SELECT tablename = o.name,

             reservedpages = sum(a.total_pages),

             usedpages = sum(a.used_pages),

             pages = sum(

                 CASE

                   When a.type <> 1 Then a.used_pages

                           When p.index_id < 2 Then a.data_pages

                           Else 0

                           END

             ),

             rows = sum(

                 CASE

                           When (p.index_id < 2) and (a.type = 1) Then p.rows

                           Else 0

                           END

             )

FROM sys.partitions p

             JOIN sys.allocation_units a ON p.partition_id = a.container_id

             JOIN sys.objects o ON p.object_id = o.object_id

WHERE o.type_desc = 'USER_TABLE'

             GROUP BY o.name ) t1

LEFT OUTER JOIN (

SELECT tablename = o.name,

             reservedpages = sum(a.total_pages),

             usedpages = sum(a.used_pages)

FROM sys.partitions p

             JOIN sys.allocation_units a ON p.partition_id = a.container_id

             JOIN sys.internal_tables it ON p.object_id = it.object_id and it.internal_type IN (202,204)

             JOIN sys.objects o ON o.object_id = it.parent_id

WHERE o.type_desc = 'USER_TABLE'

GROUP BY o.name) t2 on t1.tablename = t2.tablename

 

SET NOCOUNT OFF

GO
반응형
반응형

SQL Server Management Studio에서 확인 가능하지만, 일련의 작업 과정에서 테이블의 정보를 확인하는 경우에는 스크립트를 실행하여 확인하는 것이 편리합니다.

다음에 테이블과 관련되는 몇 가지 정보를 확인하는 스크립트 예제가 있습니다.

 

n       FOREIGN KEY 제약 조건 정보 확인하기

[따라하기] FOREIGN KEY 제약 조건 확인하기

Customers 테이블을 비활성화 되어 있는 FOREIGN KEY 제약 조건을 포함한 FOREIGN KEY 제약 조건의 FOREIGN KEY 참조하고 있는 테이블과 열의 기본 정보를 반환합니다.

USE AdventureWorks;

EXEC sp_fkeys N' Sales.Customer';

GO

 

n       테이블의 인덱스 정보 확인하기

[따라하기] 테이블 인덱스 목록 조회하기

USE AdventureWorks;

EXEC sp_helpindex N'Sales.Customer';

GO

 

n       테이블의 제약 조건 정보 확인하기

[따라하기] 테이블 관련 모든 제약 조건 조회하기

USE AdventureWorks;

EXEC sp_helpconstraint 'Production.Product';

GO

 

n       테이블의 모든 정보 확인하기

[따라하기] 테이블에 관련된 , 인덱스, 제약 조건, 참조하는 확인하기

USE AdventureWorks;

EXEC sp_help 'Person.Contact';

GO

 

[참고] SQL Server 2005에서의 sp_help 테이블 이외에도 sys.sysobjects 있는 데이터베이스 개체, 사용자 정의 데이터 형식, 데이터 형식에 관련된 정보를 반환합니다.

반응형
반응형

데이터베이스를 관리하다 보면 개체(OBJECT)의 이름을 변경할 필요가 발생합니다.

사용자가
만든 개체의 이름을 변경할 있습니다만, 개체 이름을 변경하면 스크립트나 저장 프로시저가 작동되지 않을 있으므로 사전에 충분한 확인이 필요합니다.
그리고 저장 프로시저, 트리거, 사용자 정의 함수, 뷰는 이름을 변경하지 않는 것을 권고합니다. 저장 프로시저, 트리거, 사용자 정의 함수, 뷰에 대하여 이름을 변경할 필요가 발생하는 경우에는 이름을 변경하는 대신 개체를 삭제하고 새로운 이름으로 다시 만듭니다저장 프로시저, 트리거, 사용자 정의 함수, 뷰를 다시 생성하는 경우에는 이전과 동일하게 권한을 설정하는 작업이 부가적으로 필요합니다.

 

n       테이블 이름 변경하기

[따라하기] 테이블 이름 변경하기

EXEC sp_rename 'Territories', 'Territs'

GO

 

n       인덱스 이름 변경하기

표준화된 명명 규칙에 따라 인덱스의 이름을 변경할 있습니다. 또한 예를 들어, 쿼리에서 강제로 어떤 인덱스를 사용하도록 인덱스 힌트를 사용한 경우에 인덱스의 이름에 HINT 접두어를 추가하여 표시함으로써 DBA 임의로 인덱스를 변경하지 않도록 경고할 사용할 수도 있습니다.

[따라하기] 인덱스 이름 변경하기

EXEC sp_rename 'Customers.PostalCode', 'IX_ZipCode', 'INDEX'

GO

 

n       제약 조건 이름 변경하기

sp_rename 사용하여 Customer 테이블을 Customers_Old으로 테이블 이름을 변경한 후에, Customers 테이블을 새로 만든다고 가정합니다. 데이터베이스 내에서 인덱스의 이름은 중복 가능하지만, PRIMARY KEY 제약 조건의 이름은 고유해야 합니다. 이런 경우에 Customers_Old 테이블의 PRIMARY KEY 제약 조건의 이름을 PK_Customers에서 PK_Customerd_Old 변경하면, 새로 만드는 Customers 테이블에 PK_Customers라는 이름의 제약조건을 만들 있습니다.

[따라하기] 제약 조건 이름 변경하기

EXEC sp_rename 'Customers_Old.PK_Customers', 'PK_Customers_Old'

GO

 

n       저장 프로시저, , 트리거 이름 변경하기

저장 프로시저 뷰의 이름을 변경하면, 프로시저 캐시를 플러시하여 모든 종속 저장 프로시저 뷰가 재컴파일 됩니다.

저장 프로시저, 사용자 함수, 또는 트리거의 이름을 변경해도 sys.sql_modules 카탈로그 뷰의 definition 열에 있는 해당 개체의 이름은 변경되지 않으므로, 문장을 사용하여 변경하지 않을 것을 권고합니다. 대신에, 개체를 삭제한 다음에 새로운 이름으로 다시 만드는 것을 권고합니다.

[따라하기]

EXEC sp_rename 'Sales by Year', 'SalesByYear';

GO

 

n       별칭 데이터 형식의 이름 변경하기

[따라하기]

CREATE TYPE Customer_SSN FROM varchar(13) NOT NULL;

GO

EXEC sp_rename 'Customer_SSN', 'SSN', 'USERDATATYPE';

GO

 

반응형
반응형

데이터베이스를 관리하다 보면 열을 변경해야 하는 경우가 발생합니다.

제 경험에 의하면, 열에 저장되는 값의 크기가 초기보다 커져서 현재의 데이터 타입으로는 원하는 값을 수용할 수 없어서 길이를 확장하는 경우가 가끔 발생합니다. 그 외에 동일한 데이터가 데이터베이스 내에 중복관리되고 있는데 테이블에 따라 데이터타입이 서로 상이하여 조인 시에 성능 저하가 발생하는 등의 문제가 발생하여 부랴부랴 데이터 타입을 동일하게 맞추는 경우도 아주 가끔이기는 하지만 발생합니다. 또는 NULL 허용으로 관리하였는데 NOT NULL로 변경하고자 하는 경우도 발생합니다.

열을 변경하는 구문은 단순하므로 작업에 어려움은 없을 겁니다.

열 데이터 타입 변경에 소요되는 시간을 사전에 제대로 예측하는 것이 필요합니다. 그를 위해서는 테스트 서버에서 사전에 테스트를 해 본 후에 작업 계획을 수립하고 실행할 것을 권고합니다.

그리고 ALTER COLUMN
대상이 되는 열에 인덱스가 존재한다면 우선 인덱스를 삭제한 ALTER COLUMN 실행해야 합니다.

 

[따라하기] nchar(3) 데이터 형식을 char(10) 데이터 형식으로 변경하기

USE Sample;

GO

SELECT * INTO ProductTest FROM AdventureWorks.Production.Product;

GO

EXEC sp_columns ProductTest;

GO

CREATE INDEX IDX_1 ON ProductTest (SizeUnitMeasureCode);

GO

/*

메시지 5074, 수준 16, 상태 1, 1

인덱스 'IDX_1'() 'SizeUnitMeasureCode' 종속되어 있습니다.

메시지 4922, 수준 16, 상태 9, 1

하나 이상의 개체가 열에 액세스하므로 ALTER TABLE ALTER COLUMN SizeUnitMeasureCode() 실패했습니다.

*/

DROP INDEX ProductTest.IDX_1;

GO

ALTER TABLE ProductTest ALTER COLUMN SizeUnitMeasureCode char(3);

GO

 

반응형
반응형

LargeTabAddNotNullCol 테이블에 DEFAULT 설정한 Addcol 열을 추가 다음에, 다시 열을 삭제하는 예제입니다. 제약 조건이 설정된 열은 제약 조건을 삭제한 , 열을 삭제합니다.

 

[따라하기] 삭제하기

USE Sample;

GO

ALTER TABLE CheckTest

ADD Addcol CHAR(100) NOT NULL CONSTRAINT DF_Addcol DEFAULT 'default value';

GO

ALTER TABLE CheckTest

DROP CONSTRAINT DF_Addcol;

GO

ALTER TABLE CheckTest

DROP COLUMN Addcol;

GO

 

반응형

+ Recent posts

반응형