database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
ㆍMS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MS-SQL Q&A 2198 게시물 읽기
No. 2198
Function based index를 MSSql 에서도 지원합니까?
작성자
이보영
작성일
2005-08-11 16:45
조회수
7,239

오라클에서 지원하는 Function based index 를 MSSql 에서도 지원하는지

알고 싶은데요

 

 

 

알려주세요~

 

이 글에 대한 댓글이 총 14건 있습니다.

안하는걸로 알고 있습니다.

 

PostgreSQL 에서도 지원하던데..  

 

MSSQL에서도 지원했으면 좋겠어요

voy님이 2005-08-11 18:34에 작성한 댓글입니다. Edit

잘 몰라서 그러는데,

Indexed View를 활용한 것과 효과가 다른가요???

 

그럼..

길가는 나그네..님이 2005-08-11 22:13에 작성한 댓글입니다. Edit

(BOL에서..)

 

인덱스된 뷰를 만들거나 인덱스된 뷰에 포함된 테이블의 행을 조작할 경우 7개의 SET 옵션에 특정 값을 할당해야 합니다. 즉, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, ANSI_NULLS, ANSI_PADDING, ANSI_WARNING SET 옵션을 ON으로 설정하고 NUMERIC_ROUNDABORT SET 옵션을 OFF로 설정해야 합니다.

위의 설정이 하나라도 다르게 설정되면 인덱스된 뷰에서 참조되는 테이블의 데이터 수정 문(INSERT, UPDATE, DELETE)이 실패하고 SQL Server에 설정 요구 사항에 위반되는 SET 옵션이 모두 표시된 오류가 나타납니다. 또한, 인덱스된 뷰에 수반되는 SELECT 문의 경우, SET 옵션의 값이 필요한 값이 아니면 SQL Server는 해당 뷰에 인덱스가 없는 것처럼 SELECT를 처리합니다. 이렇게 함으로써 위에 표시된 SET 옵션이 적용될 수 있는 경우에 쿼리 결과의 정확성을 보장합니다.

응용 프로그램이 DB-Library 연결을 사용할 경우 서버에서 7개의 모든 SET 옵션에 필요한 값이 할당되어야 합니다. (기본적으로 OLE DB 및 ODBC 연결은 ARITHABORT를 제외하면 필요한 SET 옵션을 모두 정확하게 설정합니다.)

BCP, 복제, 분산 쿼리 등 일부 작업은 위에 표시된 SET 옵션 중 하나라도 필요한 값이 아니면 인덱스된 뷰에 사용하는 해당 테이블에 대한 업데이트 실행이 실패할 수 있습니다. 대부분의 경우 ARITHABORT를 ON으로 설정하면(서버 구성 옵션의 user options를 통해) 이러한 문제를 방지할 수 있습니다.

서버의 한 데이터베이스에서 계산된 열에 대해 첫 번째로 인덱스된 뷰 또는 인덱스가 만들어지면 바로 서버 차원에서 ARITHABORT 사용자 옵션을 ON으로 반드시 설정하십시오.

인덱스된 뷰에 대한 자세한 고려 사항과 제한 사항을 보려면 비고 항목을 참조하십시오.

 

길가는 나그네..님이 2005-08-11 22:19에 작성한 댓글입니다. Edit

bol 에 나오는 옵션이야 기본으로 셋팅 되어 있습니다.

그리고 제가 보기에는 indexed view 가 그룹바이나 이런게 있을때 좀 좋더군요 좋기는 좋은데 제가 예전에 올린 영문 문서와 같이 제약사항도 많습니다. 조 아래

http://database.sarang.net/?inc=read&aid=2172&criteria=mssql&subcrit=&id=&limit=20&keyword=why+indexed&page=1

-_- 근데 오라클을 심도 있게 안해봐서 그런지 function based index 가 뭔가요?

 

누가 function based index 설명 좀 해주세요 ^^ 안 찾아보고 물어보는 센스 ~ 질문자는 알겠죠? 뭐하는넘인지

 

석이님이 2005-08-12 08:45에 작성한 댓글입니다. Edit

Function based index 란

함수를 사용한 데이터 field에 대해 인덱스를 사용하는 것을 말합니다.

 

예를들면

 

create index emp_ename_idx on emp(upper(ename));

 

이런식으로 인덱스를 생성하는 거죠.

이보영님이 2005-08-12 10:06에 작성한 댓글입니다. Edit

create table tblz
(
idx int identity(1,1)
,col1 datetime
)

-- 10번
insert into tblz values (GETDATE())
-- 1번
insert into tblz values ('20050813 10:10')

-- 실험
select CONVERT(CHAR(10),COL1,112) from tblz

-- 펑션만들기
CREATE FUNCTION dbo.UFN_GETDATE(@time datetime)
RETURNS CHAR(10)
AS
BEGIN
     DECLARE @date CHAR(10)

    SELECT @date= CONVERT(CHAR(10),@TIME,112)
   
    RETURN( @date);
END
GO

-- 펑션테스트
select  dbo.UFN_getdate(col1) from tblz

CREATE CLUSTERED INDEX IDX_DATE
 ON TBLZ (COL1 ASC)
 WITH PAD_INDEX
 , FILLFACTOR = 90

 

CREATE VIEW FUNCTIONBASEDVIEW WITH SCHEMABINDING
AS
select  dbo.UFN_getdate(col1) AS IDXDATE from dbo.tblz

-- 에러
-- 서버: 메시지 4513, 수준 16, 상태 1, 프로시저 FUNCTIONBASEDVIEW, 줄 3
-- 뷰 'FUNCTIONBASEDVIEW'을(를) 스키마 바인딩할 수 없습니다. 'dbo.UFN_getdate'은(는) 스키마 바인딩되지 않았습니다.


drop view FUNCTIONBASEDVIEW

CREATE VIEW FUNCTIONBASEDVIEW WITH SCHEMABINDING
AS
select  idx, CONVERT(CHAR(10),col1,112) AS IDXDATE from dbo.tblz

-- 성공

select * from FUNCTIONBASEDVIEW

create unique clustered index FUNCTIONBASEDVIEW_idx
 on FUNCTIONBASEDVIEW (idx asc)
-- 경고: 뷰의 SELECT 목록에 집계가 아닌 식이 있어서 최적화 프로그램에서 인덱스를 사용할 수 없습니다.

-- drop index FUNCTIONBASEDVIEW.FUNCTIONBASEDVIEW_idxdate

create nonclustered index FUNCTIONBASEDVIEW_idxdate
 on FUNCTIONBASEDVIEW (idxdate asc)

 

set showplan_text on
go
set statistics io on
set statistics profile on
set statistics time on
select idxdate from FUNCTIONBASEDVIEW where idxdate = '20050813'
set statistics io off
set statistics profile off
set statistics time off
go

 

-- SQL Server 실행 시간:
--    CPU 시간 = 0ms, 경과 시간 = 0ms.
-- SQL Server 구문 분석 및 컴파일 시간:
--  CPU 시간 = 0ms, 경과 시간 = 0ms.
-- idxdate   
-- ----------
-- 20050813 
--
-- (1개 행 적용됨)
--
-- 'tblz' 테이블. 스캔 수 1, 논리적 읽기 수 2, 물리적 읽기 수 0, 미리 읽기 수 0.
--
-- SQL Server 실행 시간:
--    CPU 시간 = 0ms, 경과 시간 = 0ms.
-- Rows        Executes    StmtText                                                                                                      StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument                                                                      DefinedValues                      EstimateRows             EstimateIO               EstimateCPU              AvgRowSize  TotalSubtreeCost         OutputList     Warnings Type                           Parallel EstimateExecutions      
-- ----------- ----------- ------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ ----------------------------------------------------------------------------- ---------------------------------- ------------------------ ------------------------ ------------------------ ----------- ------------------------ -------------- -------- ------------------------------ -------- ------------------------
-- 1           1           SELECT [idxdate]=[idxdate] FROM [FUNCTIONBASEDVIEW] WHERE [idxdate]=@1                                        4           1           0           NULL                           NULL                           NULL                                                                          NULL                               1.0                      NULL                     NULL                     NULL        3.7675019E-2             NULL           NULL     SELECT                         0        NULL
-- 1           1             |--Compute Scalar(DEFINE:([Expr1002]=Convert([tblz].[col1])))                                               4           2           1           Compute Scalar                 Compute Scalar                 DEFINE:([Expr1002]=Convert([tblz].[col1]))                                    [Expr1002]=Convert([tblz].[col1])  1.0                      0.0                      0.0000001                17          3.7675019E-2             [Expr1002]     NULL     PLAN_ROW                       0        1.0
-- 1           1                  |--Clustered Index Scan(OBJECT:([pubs].[dbo].[tblz].[IDX_DATE]), WHERE:(Convert([tblz].[col1])=[@1]))  4           3           2           Clustered Index Scan           Clustered Index Scan           OBJECT:([pubs].[dbo].[tblz].[IDX_DATE]), WHERE:(Convert([tblz].[col1])=[@1])  [tblz].[col1]                      1.0                      3.7578501E-2             9.3900002E-5             15          0.0376724                [tblz].[col1]  NULL     PLAN_ROW                       0        1.0
--
-- (3개 행 적용됨)
--
--
-- SQL Server 실행 시간:
--    CPU 시간 = 0ms, 경과 시간 = 0ms.
--
-- SQL Server 실행 시간:
--    CPU 시간 = 0ms, 경과 시간 = 0ms.
--
-- SQL Server 실행 시간:
--    CPU 시간 = 0ms, 경과 시간 = 0ms.
--
-- SQL Server 실행 시간:
--    CPU 시간 = 0ms, 경과 시간 = 0ms.


set showplan_text off
go

 
석이님이 2005-08-12 11:25에 작성한 댓글입니다. Edit

노트패드에 붙여보세요

 

석이님이 2005-08-12 11:26에 작성한 댓글입니다. Edit

SQL Server에는 Function Based Index는 없습니다.

같은 기능을 구현하려면..

 

테이블에 Computed Column를 만들고

여기에 인덱스를 걸어주면 됩니다.

 

ALTER TABLE emp ADD upper_ename AS upper(ename)

 

CREATE INDEX emp_ename_idx ON emp (upper_ename)

 

 

m님이 2005-08-12 15:56에 작성한 댓글입니다. Edit

컴퓨티드 컬럼만 인덱스를 줄수 있지

펑션을 준 컬럼에 대해서는 인덱스가 걸리지 않습니다.

select * from tblz

-- idx         col1                                                  
-- ----------- ------------------------------------------------------
-- 1           2005-08-12 10:42:47.513
-- 2           2005-08-12 10:42:47.780
-- 3           2005-08-12 10:42:47.937
-- 4           2005-08-12 10:42:48.107
-- 5           2005-08-12 10:42:48.263
-- 6           2005-08-12 10:42:48.420
-- 7           2005-08-12 10:42:48.590
-- 8           2005-08-12 10:42:48.747
-- 9           2005-08-12 10:42:48.920
-- 10          2005-08-12 10:42:49.090
-- 11          2005-08-12 10:42:49.263

ALTER TABLE TBLZ ADD col2 AS DBO.UFN_GETDATE(COL1)
select * from tblz

-- idx         col1                                                   col2      
-- ----------- ------------------------------------------------------ ----------
-- 1           2005-08-12 10:42:47.513                                20050812 
-- 2           2005-08-12 10:42:47.780                                20050812 
-- 3           2005-08-12 10:42:47.937                                20050812 
-- 4           2005-08-12 10:42:48.107                                20050812 
-- 5           2005-08-12 10:42:48.263                                20050812 
-- 6           2005-08-12 10:42:48.420                                20050812 
-- 7           2005-08-12 10:42:48.590                                20050812 
-- 8           2005-08-12 10:42:48.747                                20050812 
-- 9           2005-08-12 10:42:48.920                                20050812 
-- 10          2005-08-12 10:42:49.090                                20050812 

CREATE  INDEX  TBLX_IDX3 ON tblz (col2)
-- 서버: 메시지 1933, 수준 16, 상태 1, 줄 1
-- 키 열 'col2'이(가) 명확하지 않거나 정확하지 않으므로 인덱스를 만들 수 없습니다.

석이님이 2005-08-12 17:16에 작성한 댓글입니다. Edit

확정적 함수와 비확정적 함수...

표현이 맞는지 모르겠지만, 어쨌던 확정적 함수라면 인덱스 걸어줄 수 있지 않나요??

 

그럼..

길가는 나그네..님이 2005-08-12 17:18에 작성한 댓글입니다.
이 댓글은 2005-08-12 17:20에 마지막으로 수정되었습니다. Edit

비확정 함수는 유저 펑션이 만들어지지도 않습니다.

CREATE FUNCTION dbo.UFN_GETDATE(@time datetime)
RETURNS CHAR(10)
AS
BEGIN
     DECLARE @date CHAR(10)

    SELECT @date= CONVERT(CHAR(10),@TIME,112)
   
    RETURN( @date);
END

 

석이님이 2005-08-12 17:21에 작성한 댓글입니다. Edit

그렇네요..

그냥 봐서는 될 것 같은데, 안 되네요.. ^^;;

 

이하 샘플)


create function dbo.get(@a int, @b int)
returns int
as
begin
  return(@a + @b)
end

go

 

create table a(
  a int
, b int
, c as (a+b)
, d as dbo.get(a, b)
)

go

 

insert into a values (1,2)
insert into a values (2,3)
insert into a values (3,4)
insert into a values (4,5)
insert into a values (5,6)

 

select * from a

go

 

create index idxa on a(c)

go
create index idxa on a(d)

go

 

drop table a
drop function dbo.get

길가는 나그네..님이 2005-08-12 17:29에 작성한 댓글입니다.
이 댓글은 2005-08-12 17:32에 마지막으로 수정되었습니다. Edit

oracle의 function base index 는 mssql에서도 생성하여 구현하는 것이 가능합니다.

하지만...오라클과 똑같이 어떤 특정 컬럼에 대한 변환 값이나 기타 조건에 모두 적용할수 있는 것은 아닙니다.

그리고 oracle 에서는 funcation base index 를 구현할때는 특정 파라미터나 기타 전체 옵티마이져 및 통계정보및 여러 가지 인스턴스 레벨에서의 제약이 많습니다.

 

 물론  mssql에서도 몇가지의 제약이 있긴합니다.

같은 값들을 반환하는 이른바 확정된 함수에서는 가능하며.. 그밖에 비 확정된 함수는 function base index를 사용하는 것이 불가 합니다.

물론 서버의 셋팅값은 윗분들이 잘 적어 주셨네요... 다만 함수의 여부에 따라서 사용여부가 가능해 지겠죠... ^^

 사용하는데 따른 제약 조건이 상당히 많습니다.

 

이걸 mssql에서 function base index 라고 불러야 되나 하는 생각이 들지만.. 기본 사용 포멧은 비슷하다고 볼수 있게죠..

해당 컬럼의 변형에 의한 인덱스의 사용을 가능하게 해 주는 역할을 하기 때문에... 저는 그렇게 부르고 사용하고 있씁니다.

 

 물론 mssql 은 기본이 cbo 이기 때문에 사용이 가능합니다.

하지만... 기본적으로 이 function base index 는 사용하지 않는 것이 바람직 하겠죠... 오라클에서 사용을 권장하지는 않습니다.

그만큼 서버 내부적인 파싱비용및 기타 비용들이 많이 들기 때문에.. 가능한 해당 컬럼의 변형을 하지 않은 체로 가공하여 정상적인 인덱스를 옵티마이져가 선택하게 해 주는 것이 바른 판단입니다.

 수고하세요

sqler님이 2005-08-17 10:19에 작성한 댓글입니다. Edit

sqler 님 뭘 mssql 의 function based index 라 하시는지 그리고 indexed view 를 이용한 방법이 아니고 다른 방법이라는 말씀이신지

예제는 어떻게 되는지 좀 적어주시면 감사하겠습니다.

펑션에 기본적으로 인덱스 안걸리거든요

 

석이님이 2005-08-17 10:52에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
2204세미나 정보 [1]
석이
2005-08-14
1710
2203원격지의 MS-SQL을 로컬로 백업할수있나요? [1]
MSSQL초보
2005-08-12
4545
2202코드테이블을 따로 관리할경우 쿼리문제입니다.. [5]
chslove
2005-08-11
1988
2198Function based index를 MSSql 에서도 지원합니까? [14]
이보영
2005-08-11
7239
2196CHAR형식을 데이터 타입으로 ..... [3]
쉬는초보
2005-08-10
3469
2195데이타베이스가 안만들어지네요.(xpstar.dll 로드문제) [1]
질문자
2005-08-10
3096
2194테이블 구조에 대한 질문요~ [3]
황하근
2005-08-10
2408
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다