그들은 실제로 동일하지만, 그들은 독립적 인 유형 및없는 기술적으로 동의어, 같은 ROWVERSION
과 TIMESTAMP
- 비록 그들이 한 번에 문서에서 동의어로 언급되었을 수 있습니다 . 이는 동의어의 약간 다른 의미입니다 (예 : 이름을 제외하고는 구별 할 수 없으며, 하나는 다른 별명이 아닙니다). 아이러니하지?
MSDN의 문구에서 내가 해석하는 것은 실제로 다음과 같습니다.
이 유형은 동일하며 이름이 다릅니다.
type_id
값 이외의 모든 내용은 동일합니다.
SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');
나는 둘 사이의 동작 차이에 대해 전혀 알지 못하고 SQL Server 6.5로 돌아가서 항상 100 % 상호 교환 가능한 것으로 취급했습니다.
DECIMAL (18,2) 및 NUMERIC (18,2)의 경우 하나를 다른 것으로 할당하는 것은 기술적으로 "전환"입니까?
명시 적으로 그렇게하는 경우에만 가능합니다. 테이블을 만든 다음 명시 적 또는 암시 적 변환을 수행하는 쿼리에 대한 쿼리 계획을 검사하여이를 쉽게 증명할 수 있습니다. 다음은 간단한 테이블입니다.
CREATE TABLE [dbo].[NumDec]
(
[num] [numeric](18, 0) NULL,
[dec] [decimal](18, 0) NULL
);
이제 다음 쿼리를 실행하고 계획을 캡처하십시오.
DECLARE @num NUMERIC(18,0);
DECLARE @dec DECIMAL(18,0);
SELECT
CONVERT(DECIMAL(18,0), [num]), -- conversion
CONVERT(NUMERIC(18,0), [dec]) -- conversion
FROM dbo.NumDec
UNION ALL SELECT [num],[dec]
FROM dbo.NumDec WHERE [num] = @dec -- no conversion
UNION ALL SELECT [num],[dec]
FROM dbo.NumDec WHERE [dec] = @num; -- no conversion
에 나타낸 바와 같이 SQL 센트리 계획 탐색기 *, 계획은 정말 흥미로운되지 않습니다 :
그러나 표현식 탭은 다음과 같습니다.
위에서 언급했듯이 요청한 부분에 명시적인 전환이 있지만 예상했던 부분에 대한 명시적인 전환은 없습니다. 옵티마이 저도 그것들을 상호 교환 가능한 것으로 취급합니다.
계속해서이 테스트 (데이터 및 인덱스)를 시도하십시오.
CREATE TABLE [dbo].[NumDec2]
(
[num] [numeric](18, 2) NULL,
[dec] [decimal](18, 2) NULL
);
INSERT dbo.NumDec2([num],[dec])
SELECT [object_id] + 0.12, [object_id] + 0.12
FROM sys.all_columns;
CREATE INDEX [ix_num] ON dbo.NumDec2([num]);
CREATE INDEX [ix_dec] ON dbo.NumDec2([dec]);
이제이 쿼리를 실행하십시오.
DECLARE @num NUMERIC(18,2) = -1291334356.88,
@dec NUMERIC(18,2) = -1291334356.88;
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = @num
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = @dec;
계획에 변환이 없습니다 (사실 식 탭이 비어 있음).
이것조차도 예기치 않은 전환으로 이어지지는 않습니다. 물론, 술어의 RHS에서이를 볼 수 있지만, 탐색을 용이하게하기 위해 열 데이터에 대해 변환을 수행 할 필요는 없습니다 (스캔이 훨씬 적음).
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(DECIMAL(18,2), @num)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(DECIMAL(18,2), @dec)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(NUMERIC(18,2), @num)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(NUMERIC(18,2), @dec)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(DECIMAL(18,2), @num)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(DECIMAL(18,2), @dec)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(NUMERIC(18,2), @num)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(NUMERIC(18,2), @dec);
개인적으로 저는이 용어 DECIMAL
가 훨씬 정확하고 설명 적이 라는 용어를 사용하는 것을 선호합니다 . BIT
"숫자"입니다.
* Disclaimer: I work for SQL Sentry.