この質問はすでに尋ねられています here が、XML変数のサイズなどを見つけるのに役立つ回答はありませんでした。
declare @myVariable XML
私はこの質問から学んだ: SQLサーバーでXML = ''かどうかをテストする方法?
XMLデータの内部表現がバージョン間で変更される可能性もありますが、SQL Server 2008 R2、2012、および2014でテストし、空のXMLアイテムのサイズが常に5であることにも注意してください。
各SQL Serverデータ型のサイズを確認するにはどうすればよいですか?
XMLのサイズが5であることをどのように証明できますか?
これはすべて、ストアドプロシージャをチューニングしていて、XMLをパラメーターとして使用しているときに始まりました パフォーマンスの向上-SQL Server 2005でパラメーターとしてテーブルを渡す方法
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
オプションと同じように動作します。これは、DATALENGTH
がdatatype(変数と列の両方に適用されます)によって使用されたバイト数を報告するが、SPARSE
オプションとデータ圧縮によってストレージの最適化です(列にのみ適用されます)。