web-dev-qa-db-ja.com

SQL Serverデータ型のサイズはどこにありますか?

この質問はすでに尋ねられています here が、XML変数のサイズなどを見つけるのに役立つ回答はありませんでした。

declare @myVariable XML

私はこの質問から学んだ: SQLサーバーでXML = ''かどうかをテストする方法?

XMLデータの内部表現がバージョン間で変更される可能性もありますが、SQL Server 2008 R2、2012、および2014でテストし、空のXMLアイテムのサイズが常に5であることにも注意してください。

各SQL Serverデータ型のサイズを確認するにはどうすればよいですか?

XMLのサイズが5であることをどのように証明できますか?

これはすべて、ストアドプロシージャをチューニングしていて、XMLをパラメーターとして使用しているときに始まりました パフォーマンスの向上-SQL Server 2005でパラメーターとしてテーブルを渡す方法

2

XMLのサイズが5であることをどのように証明できますか?

この質問は、「variable-lengthSQL Serverデータ型のサイズはどこにありますか?」

可変長型の問題は、特定の変数または列に現在格納されているデータにすべて依存するため、どこにでも文書化できる特定のサイズがないことです。そして現在のサイズを知る唯一の方法は [〜#〜] datalength [〜#〜] 組み込み関数を使用することです。例えば:

DECLARE @TestXML XML;
SELECT DATALENGTH(@TestXML);

SET @TestXML = N'';
SELECT DATALENGTH(@TestXML);

SET @TestXML = N'g';
SELECT DATALENGTH(@TestXML);
GO

どちらが戻ります:

NULL
5
9

現在、XMLデータ型は、.value.nodes.query、および.existに便利なアクセス関数を提供するだけではありません。タグと属性名のディクショナリを作成し、テキストを検索可能なIDに置き換えることにより、物理ストレージが削減されるという点で「最適化」されています。したがって、XML文書の内部表現は、XML文書を見るときに表示されるものとは異なります。

以下に示すように、NVARCHAR文字列は、UTF-16(リトルエンディアン)であり、47文字(予想どおり)であるため、94バイトです。 VARCHARに変換された同じ値は、それらの47文字に対して(予想どおり)47バイトしか使用しません。ただし、XMLに変換すると、サイズはバイト単位で53になります。それはどうですか? 「row」および「col」タグのテキストは(内部ディクショナリに)1回だけ記録され、IDはドキュメントの内部階層で使用されます。

DECLARE @TestNVARCHAR NVARCHAR(500);
SET @TestNVARCHAR = N'<row><col>1</col><col>2</col><col>3</col></row>';

SELECT LEN(@TestNVARCHAR) AS [LEN], DATALENGTH(@TestNVARCHAR) AS [DATALENGTH];
-- 47   94

DECLARE @TestVARCHAR VARCHAR(500);
SET @TestVARCHAR = CONVERT(VARCHAR(500), @TestNVARCHAR);

SELECT LEN(@TestVARCHAR) AS [LEN], DATALENGTH(@TestVARCHAR) AS [DATALENGTH];
-- 47   47

DECLARE @TestXMLfromNVARCHAR XML;
SET @TestXMLfromNVARCHAR = CONVERT(XML, @TestNVARCHAR);

SELECT @TestXMLfromNVARCHAR, DATALENGTH(@TestXMLfromNVARCHAR) AS [DATALENGTH];
-- <row><col>1</col><col>2</col><col>3</col></row>  53

これはまた、空白とフォーマットが無視され、選択されたXML値のフォーマットが、設定/挿入されたときのフォーマットと正確に同じにならない場合がある理由でもあります。

DECLARE @EmptyTag XML;
SET @EmptyTag = N'<test></test>             <test></test>';
SELECT @EmptyTag;
-- <test /><test />

ただし、DATALENGTHが正確に表示されない場合は少なくとも2つあります。SPARSEデータとデータ圧縮です。 SPARSEオプション(SQL Server 2008で導入)では、固定長の型はNULLの場合は0バイトを使用できますが、NOT NULLの場合は標準サイズに4バイトを追加できます。ただし、ここでは正しく表示されません。

DECLARE @TestSPARSE TABLE
(
  RowID INT NOT NULL,
  Col1 BIGINT SPARSE NULL,
  Col2 TINYINT SPARSE NULL
);
INSERT INTO @TestSPARSE ([RowID], [Col1], [Col2]) VALUES (1, 0, 0);
INSERT INTO @TestSPARSE ([RowID], [Col1], [Col2]) VALUES (2, NULL, NULL);

SELECT RowID,
       Col1,
       DATALENGTH([Col1]) AS [BytesCol1],
       Col2,
       DATALENGTH([Col2]) AS [BytesCol2]
FROM   @TestSPARSE;

戻り値:

RowID    Col1    BytesCol1    Col2    BytesCol2
1        0       8            0       1
2        NULL    NULL         NULL    NULL

このような場合、DBCC PAGEを使用して実際のデータページの実際の行を表示し、実際に何が起こっているかを確認する必要があります。

データ圧縮は、SPARSEによって報告される値への影響(またはその欠如)に関して、DATALENGTHオプションと同じように動作します。これは、DATALENGTHdatatype(変数と列の両方に適用されます)によって使用されたバイト数を報告するが、SPARSEオプションとデータ圧縮によってストレージの最適化です(列にのみ適用されます)。

3
Solomon Rutzky