SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Database の JSON データ型の格納効率について

leave a comment

SQL Database / SQL Server 2025 では、JSON データ型  をサポートしており、JSON フォーマットのデータを格納するための専用のデータ型を使用することができます。

JSON データ型は「Latin1_General_100_BIN2_UTF8」の照合順序により UTF-8 のエンコードが使用されるという特徴の他に「圧縮用に最適化された、より効率的なストレージ」もメリットとして挙げられています。

通常の文字列データ型と比較して、JSON データ型がどの程度ストレージの格納効率が変化するのかが気になったので、SQL Database で確認してみました。

ストレージ格納効率の比較

今回は文字列データ型との格納効率を比較するため、同一のデータで次のデータ型で JSON フォーマットのデータを表現しています。

  • nvarchar(max): UTF-16
  • varchar(max): Shift JIS
  • varchar(max): UTF-8
  • json

 

JSON データ型のほうが格納効率が悪いケース

JSON フォーマットのデータの生成については、カラムの情報を使用した次のようなクエリで JSON AUTO を使用して生成を行い、DATALENGTH を使用してバイト数の取得を行います。

SELECT
	SUM(DATALENGTH(CAST(json_data AS nvarchar(max)))) AS nvarchar_max,
	SUM(DATALENGTH(CAST(json_data COLLATE Japanese_XJIS_140_CI_AS AS varchar(max)))) AS varchar_max,
	SUM(DATALENGTH(CAST(json_data COLLATE Japanese_XJIS_140_CI_AS_UTF8 AS varchar(max)))) AS varchar_max_utf8,
	SUM(DATALENGTH(CAST(json_data AS json))) AS json
FROM
(
SELECT TOP 1000
	(SELECT * FROM sys.all_columns AS T2 WHERE T2.object_id = T1.object_id 
	AND T2.column_id = T1.column_id 
	FOR JSON AUTO,WITHOUT_ARRAY_WRAPPER) AS json_data
FROM 
	sys.all_columns AS T1
ORDER BY object_id DESC
) AS T
GO

 

このクエリでは次のような JSON のデータが生成されています

{
    "object_id": -1072372588,
    "name": "GRANTOR",
    "column_id": 1,
    <省略>
    "is_masked": false,
    "is_data_deletion_filter_column": false,
    "is_dropped_ledger_column": false
}

 

シンプルな 1 レコードの JSON が生成されるクエリとなっており、この JSON データの格納効率を確認しています。今回は Shift JIS と UTF-8 の格納効率の違いを出すようにしているため、テーブルに日本語列を作成して差が出るようにしています。

実際の取得結果が次のようになります。

image

今回のケースであれば、「varchar(max)」が使用されるデータサイズが一番小さくなっています。文字列データ型の格納効率の違いについては UTF-8 と UTF-16 でのストレージの相違点 に記載されていますが、Shift JIS で表現できる文字であれば Shift JIS の varchar(max) を使用するのが一番サイズが小さくなっています。

今回のデータであれば、「nvarchar(max) > json > varchar(max): UTF-8 > varchar(max): Shift JIS」という関係になっています。

JSON データ型の特徴として、冒頭に記載した「圧縮用に最適化された、より効率的なストレージ」がありますが、これは、単一レコードの JSON データ型では効果はなく、シンプルな JSON データの場合は JSON データ型ではなく、varchar(max) にデータを格納したほうが効率が良いケースがあるようです。

 

JSON データ型のほうが格納効率が良いケース

JSON データ型のほうが格納効率が良いケースですが次のようなクエリの場合は、JSON データ型のほうが格納効率が良くなります。

SELECT
	SUM(DATALENGTH(CAST(json_data AS nvarchar(max)))) AS nvarchar_max,
	SUM(DATALENGTH(CAST(json_data COLLATE Japanese_XJIS_140_CI_AS AS varchar(max)))) AS varchar_max,
	SUM(DATALENGTH(CAST(json_data COLLATE Japanese_XJIS_140_CI_AS_UTF8 AS varchar(max)))) AS varchar_max_utf8,
	SUM(DATALENGTH(CAST(json_data AS json))) AS json
FROM
(
SELECT TOP 1000
	(SELECT TOP 5 * FROM sys.all_columns AS T2 WHERE T2.object_id = T1.object_id 
	FOR JSON AUTO) AS json_data
FROM 
	sys.all_columns AS T1
ORDER BY object_id DESC
) AS T
GO

 

このクエリでは、次のような JSON のデータが生成されています。

[
    {
        "object_id": -1072372588,
        "name": "GRANTOR",
        "column_id": 1,
        <省略>
        "is_masked": false,
        "is_data_deletion_filter_column": false,
        "is_dropped_ledger_column": false
    },
    {
        "object_id": -1072372588,
        "name": "GRANTEE",
        "column_id": 2,
        <省略>
        "is_masked": false,
        "is_data_deletion_filter_column": false,
        "is_dropped_ledger_column": false
    },
    {
        "object_id": -1072372588,
        "name": "TABLE_CATALOG",
        "column_id": 3,
        <省略>
        "is_masked": false,
        "is_data_deletion_filter_column": false,
        "is_dropped_ledger_column": false
    },
    {
        "object_id": -1072372588,
        "name": "TABLE_SCHEMA",
        "column_id": 4,
        <省略>
        "is_masked": false,
        "is_data_deletion_filter_column": false,
        "is_dropped_ledger_column": false
    },
    {
        "object_id": -1072372588,
        "name": "TABLE_NAME",
        "column_id": 5,
        <省略>
        "is_masked": false,
        "is_data_deletion_filter_column": false,
        "is_dropped_ledger_column": false
    }
]

 

このような JSON データを格納した場合は、格納効率が異なってきます。

image

先ほどの結果は、「nvarchar(max) > json > varchar(max): UTF-8 > varchar(max): Shift JIS」となっていました。

今回のデータでは、「nvarchar(max) > varchar(max): UTF-8 > varchar(max): Shift JIS > json」となっており、JSON データ型が一番格納効率が高くなっています。

単一レコードの JSON データ型ではなく、類似のフォーマットをデータが複数レコード格納されている場合は、JSON データ型のほうが格納効率が良いという傾向があるようです。

JSON データ型をストレージの格納効率の最適化を目的として使用する場合、実際に格納されるデータを DATALENGTH でバイト数を確認し、圧縮による効果があるのかを確認すると良いのかもしれませんね。

Share

Written by Masayuki.Ozawa

2月 19th, 2025 at 10:53 pm

Leave a Reply