すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:オブジェクトのクエリ実行

最終更新日:Mar 20, 2026

SelectObject を使用すると、Object Storage Service (OSS) 内のオブジェクトに対して直接 SQL クエリを実行し、対象データのみを取得できます。この機能により、オブジェクト全体を事前にダウンロードする必要がなくなり、帯域幅の消費量を削減するとともに、クライアント側の CPU 使用率およびメモリ使用量を低減できます。これにより、OSS を基盤としたデータ分析の効率性が向上します。

仕組み

GetObject を使用する場合、アプリケーションはフィルタリング処理を行う前にオブジェクト全体をダウンロードします。一方、SelectObject ではフィルタリング処理を OSS 側に移動させます。つまり、SQL 条件式およびプロジェクション(列選択)を OSS に送信すると、OSS が該当する行のみを返却します。

クエリのフローは以下のとおりです:

  1. SQL SELECT ... FROM ... WHERE ステートメントおよび出力フォーマットを指定して SelectObject リクエストを送信します。

  2. OSS がオブジェクトをスキャンし、条件およびプロジェクションをサーバー側で適用します。

  3. OSS が該当するレコードのみをストリーム形式でクライアントに返却します。

  4. ラージオブジェクトの場合、まず CreateSelectObjectMeta を呼び出して分割数(splits)の合計値を取得した後、split-range を使用して並列クエリを実行します。

サポートされるオブジェクトタイプ

タイプ詳細
CSV(TSV および類似フォーマットを含む)RFC 4180 に準拠している必要があります。カスタムの行区切り文字、列区切り文字、および引用符文字をサポートします。
JSON(UTF-8 エンコーディング)2 種類のフォーマットに対応: JSON DOCUMENT(単一の JSON オブジェクト)および JSON LINES(各行に 1 つの JSON オブジェクトを記述、\n または \r\n で区切る。デリミタの構成は不要)。
標準ストレージおよび低頻度アクセス(IA)オブジェクト直接クエリ可能です。アーカイブ、コールドアーカイブ、およびディープコールドアーカイブストレージのオブジェクトは、クエリ実行前に解凍する必要があります。
暗号化されたオブジェクトOSS が管理する暗号化または Key Management Service (KMS) が管理するカスタマーマスターキー(CMK)による暗号化が適用されたオブジェクト。

制限事項

制限詳細
サポートされないバケットタイプゾーン属性(no-header-region)を持たないバケットでは SelectObject はサポートされていません。
コンソールでのデータ制限OSS コンソールでは、最大 128 MB のサイズのオブジェクトから最大 40 MB のデータを選択できます。
SDK のサポート状況SelectObject は、OSS SDK for Java および OSS SDK for Python のみでサポートされています。
圧縮圧縮済みオブジェクトのクエリでは、GZIP 圧縮のみがサポートされています。
LIKE の大文字小文字の区別LIKE を使用したあいまい一致は、大文字小文字を区別します。

課金

SelectObject の課金は、スキャンされるデータ量に基づきます:

  • 標準オブジェクト:データスキャン料金。

  • 低頻度アクセス(IA)、アーカイブ、コールドアーカイブ、およびディープコールドアーカイブストレージのオブジェクト:データスキャン料金に加え、データ取得料金も発生します。

料金の詳細については、「データ処理料金」をご参照ください。

サポートされる SQL 構文

カテゴリサポート状況
ステートメントSELECT ... FROM ossobject [WHERE ...]
データ型stringint(64 ビット)、double(64 ビット)、decimal(128 ビット)、timestampbool
論理演算子ANDORNOT
算術演算子+-*/%
比較演算子>=<>=<=!=
文字列演算子LIKE||(連結)
集計関数COUNTMAXMINAVGSUM
型変換CAST 関数

CSV と JSON におけるデータ型の違い

CSV データはデフォルトで string 型として扱われます。CAST を使用して明示的に型変換を行います:

SELECT s.a FROM ossobject s WHERE CAST(s.a AS decimal) > 123456789.12345

JSON オブジェクトは元の型(Null、Bool、Int64、Double、String)を保持します。高精度の浮動小数点数を処理する場合は、ParseJsonNumberAsStringtrue に設定し、decimal 型へキャストします:

SELECT s.a FROM ossobject s WHERE CAST(s.a AS decimal) > 123456789.12345

SQL の使用例

CSV クエリ

CSV の列インデックスは _1 から始まります。CSV にヘッダー行が含まれる場合、列名で参照できます。

目的SQL ステートメント
先頭 10 行を返すSELECT * FROM ossobject LIMIT 10
列 1(int)> 列 3(int)を満たす行を返すSELECT _1, _3 FROM ossobject WHERE CAST(_1 AS int) > CAST(_3 AS int)
列 1 の値が「X」で始まる行の数をカウントするSELECT COUNT(*) FROM ossobject WHERE _1 LIKE 'X%'
列 2 の値が特定のタイムスタンプ以降であり、かつ列 3 の値が 200 より大きい行を返すSELECT * FROM ossobject WHERE _2 > CAST('2018-08-09 11:30:25' AS timestamp) AND _3 > 200
列 6(double)に対する集計関数を実行するSELECT AVG(CAST(_6 AS double)), SUM(CAST(_6 AS double)), MAX(CAST(_6 AS double)), MIN(CAST(_6 AS double)) FROM ossobject
パターンに一致する連結された列SELECT * FROM ossobject WHERE (_1 || _3) LIKE 'Tom%Anderson'
列 1 の値が 3 で割り切れる行を返すSELECT * FROM ossobject WHERE (_1 % 3) = 0
列 1 の値が 1995 ~ 2012 の範囲内である行を返すSELECT * FROM ossobject WHERE _1 BETWEEN 1995 AND 2012
列 5 の値が N、M、G、L のいずれかである行を返すSELECT * FROM ossobject WHERE _5 IN ('N', 'M', 'G', 'L')
(列 2 × 列 3)>(列 5 + 100)を満たす行を返すSELECT * FROM ossobject WHERE _2 * _3 > _5 + 100

JSON クエリ

ネストされた構造体を操作するには、ドット表記および配列ワイルドカードを使用します。FROM 句でパスを絞り込むと、パフォーマンスが向上します。

次のサンプルオブジェクトを例に説明します:

{
  "contacts": [
    {
      "firstName": "John",
      "lastName": "Smith",
      "age": 27,
      "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": "10021-3100"
      },
      "phoneNumbers": [
        { "type": "home", "number": "212 555-1234" },
        { "type": "office", "number": "646 555-4567" },
        { "type": "mobile", "number": "123 456-7890" }
      ],
      "children": [],
      "spouse": null
    }
  ]
}
目的SQL ステートメント
年齢が 27 の連絡先を取得するSELECT * FROM ossobject.contacts[*] s WHERE s.age = 27
すべての自宅の電話番号SELECT s.number FROM ossobject.contacts[*].phoneNumbers[*] s WHERE s.type = 'home'
配偶者が null の連絡先を取得するSELECT * FROM ossobject s WHERE s.spouse IS NULL
子配列が空の連絡先SELECT * FROM ossobject s WHERE s.children[0] IS NULL
郵便番号が「10021」で始まる住所を取得するSELECT s.streetAddress FROM ossobject.contacts[*].address s WHERE s.postalCode LIKE '10021%'
説明

FROM 句のパスを絞り込む(例:ossobject.contacts[*].address)方が、広範なパスを指定した後にドット表記でアクセスする方法(例:ossobject.contacts[*] の後に s.address.streetAddress)よりも効率的です。

OSS コンソールを使用したオブジェクトのクエリ実行

重要

コンソールでは、最大 128 MB のサイズのオブジェクトから最大 40 MB のデータを選択できます。

  1. OSS コンソールにログインします。

  2. 左側のナビゲーションウィンドウで、バケット をクリックします。対象のバケットを検索してクリックします。

  3. 左側のナビゲーションツリーで、オブジェクト管理 > オブジェクト を選択します。

  4. 対象オブジェクトの 操作 列で、more > コンテンツの選択 を選択します。

  5. コンテンツの選択 パネルで、以下のパラメーターを設定します:

    パラメーター説明
    オブジェクトタイプCSV または JSON
    デリミタCSV のみ対応。, またはカスタム
    タイトル行CSV のみ対応。1 行目が列ヘッダーを含むかどうか
    JSON 表示モードJSON のみ対応。JSON_LINES または JSON_DOCUMENT
    圧縮フォーマットGZIP のみ対応
  6. プレビュー をクリックして、選択したデータをプレビューします。

    重要

    標準ストレージオブジェクトのプレビューにはデータスキャン料金が発生します。低頻度アクセス(IA)、アーカイブ、コールドアーカイブ、およびディープコールドアーカイブストレージのオブジェクトのプレビューには、データスキャン料金に加えてデータ取得料金も発生します。詳細については、「データ処理料金」をご参照ください。

  7. 次へ をクリックし、SQL ステートメントを入力して実行します。例:CSV オブジェクト People には、NameCompanyAge の 3 つの列があり、それぞれの列インデックスは _1(Name)、_2(Company)、_3(Age)です。

    • 名前が「Lora」で始まり、年齢が 50 を超える人物をクエリする:

      SELECT * FROM ossobject WHERE _1 LIKE 'Lora*' AND _3 > 50
    • 行数、最大年齢、最小年齢を取得する:

      SELECT COUNT(*), MAX(CAST(_3 AS int)), MIN(CAST(_3 AS int)) FROM oss_object
  8. 結果を表示します。ダウンロード をクリックして、出力をローカルマシンに保存します。

OSS SDK を使用したオブジェクトのクエリ実行

SelectObject は、OSS SDK for Java および OSS SDK for Python のみでサポートされています。

Java の使用例

Java SDK では、createSelectObjectMetadata を使用して分割メタデータを生成し、selectObject を使用してクエリを実行します。認証情報は環境変数 OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET から読み込まれます。

import com.aliyun.oss.model.*;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;

public class SelectObjectSample {
    // バケットのリージョンに対応するエンドポイントに置き換えます。
    // 例: https://oss-cn-hangzhou.aliyuncs.com
    private static String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    private static String bucketName = "examplebucket";

    public static void main(String[] args) throws Exception {
        // 環境変数 OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET から認証情報を読み込みます。
        EnvironmentVariableCredentialsProvider credentialsProvider =
            CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        String region = "cn-hangzhou";

        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)
            .build();

        // CSV オブジェクトをクエリします。
        selectCsvSample("test.csv", ossClient);
        // JSON LINES オブジェクトをクエリします。
        selectJsonSample("test.json", ossClient);

        ossClient.shutdown();
    }

    private static void selectCsvSample(String key, OSS ossClient) throws Exception {
        // ヘッダー行を含むサンプル CSV データをアップロードします。
        String content = "name,school,company,age\r\n" +
                "Lora Francis,School A,Staples Inc,27\r\n" +
                "Eleanor Little,School B,\"Conectiv, Inc\",43\r\n" +
                "Rosie Hughes,School C,Western Gas Resources Inc,44\r\n" +
                "Lawrence Ross,School D,MetLife Inc.,24";
        ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));

        // オブジェクトの分割メタデータを生成します(マルチパートクエリの前に推奨)。
        SelectObjectMetadata selectObjectMetadata = ossClient.createSelectObjectMetadata(
            new CreateSelectObjectMetadataRequest(bucketName, key)
                .withInputSerialization(
                    new InputSerialization().withCsvInputFormat(
                        new CSVFormat()
                            .withHeaderInfo(CSVFormat.Header.Use)
                            .withRecordDelimiter("\r\n"))));
        System.out.println("Total lines: " + selectObjectMetadata.getCsvObjectMetadata().getTotalLines());
        System.out.println("Total splits: " + selectObjectMetadata.getCsvObjectMetadata().getSplits());

        // 4 列目(年齢)が 40 より大きい行をクエリします。
        SelectObjectRequest selectObjectRequest =
            new SelectObjectRequest(bucketName, key)
                .withInputSerialization(
                    new InputSerialization().withCsvInputFormat(
                        new CSVFormat()
                            .withHeaderInfo(CSVFormat.Header.Use)
                            .withRecordDelimiter("\r\n")))
                .withOutputSerialization(new OutputSerialization().withCsvOutputFormat(new CSVFormat()));
        selectObjectRequest.setExpression("SELECT * FROM ossobject WHERE _4 > 40");

        OSSObject ossObject = ossClient.selectObject(selectObjectRequest);
        BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        reader.close();
        ossClient.deleteObject(bucketName, key);
    }

    private static void selectJsonSample(String key, OSS ossClient) throws Exception {
        // サンプル JSON LINES データ(1 行につき 1 つの JSON オブジェクト)をアップロードします。
        final String content = "{\"name\":\"Lora Francis\",\"age\":27,\"company\":\"Staples Inc\"}\n" +
                "{\"name\":\"Eleanor Little\",\"age\":43,\"company\":\"Conectiv, Inc\"}\n" +
                "{\"name\":\"Rosie Hughes\",\"age\":44,\"company\":\"Western Gas Resources Inc\"}\n" +
                "{\"name\":\"Lawrence Ross\",\"age\":24,\"company\":\"MetLife Inc.\"}";
        ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));

        // 年齢が 40 より大きいレコードをクエリします。
        SelectObjectRequest selectObjectRequest =
            new SelectObjectRequest(bucketName, key)
                .withInputSerialization(new InputSerialization()
                    .withCompressionType(CompressionType.NONE)
                    .withJsonInputFormat(new JsonFormat().withJsonType(JsonType.LINES)))
                .withOutputSerialization(new OutputSerialization()
                    .withCrcEnabled(true)
                    .withJsonOutputFormat(new JsonFormat()))
                .withExpression("SELECT * FROM ossobject AS s WHERE s.age > 40");

        OSSObject ossObject = ossClient.selectObject(selectObjectRequest);
        BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        reader.close();
        ossClient.deleteObject(bucketName, key);
    }
}

Python の使用例

Python SDK では、create_select_object_metaselect_object、および select_object_to_file が提供されます。認証情報は環境変数 OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET から読み込まれます。

import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

def select_callback(consumed_bytes, total_bytes=None):
    print(f"Consumed bytes: {consumed_bytes}")

# 環境変数から認証情報を読み込みます。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

endpoint = "https://oss-cn-hangzhou.aliyuncs.com"  # バケットのエンドポイントに置き換えます。
region = "cn-hangzhou"                              # バケットのリージョンに置き換えます。
bucket = oss2.Bucket(auth, endpoint, "examplebucket", region=region)

# --- CSV クエリ ---

key = "python_select.csv"
content = "Tom Hanks,USA,45\r\n" * 1024
bucket.put_object(key, content)

# 分割メタデータを生成します。
csv_meta_params = {"RecordDelimiter": "\r\n"}
csv_header = bucket.create_select_object_meta(key, csv_meta_params)
print(f"Total rows: {csv_header.rows}, total splits: {csv_header.splits}")

# 列 3 の値が 44 より大きい行をクエリします。
select_csv_params = {
    "CsvHeaderInfo": "None",
    "RecordDelimiter": "\r\n",
    "LineRange": (500, 1000),
}
result = bucket.select_object(
    key, "SELECT * FROM ossobject WHERE _3 > 44", select_callback, select_csv_params
)
print(result.read())

# 結果をローカルファイルに保存します。
bucket.select_object_to_file(
    key, "python_select.csv", "SELECT * FROM ossobject WHERE _3 > 44",
    select_callback, select_csv_params
)
bucket.delete_object(key)

# --- JSON DOCUMENT クエリ ---

key = "python_select.json"
content = '{"contacts":[{"key1":1,"key2":"hello world1"},{"key1":2,"key2":"hello world2"}]}'
bucket.put_object(key, content)

select_json_params = {"Json_Type": "DOCUMENT"}
result = bucket.select_object(
    key,
    "SELECT s.key2 FROM ossobject.contacts[*] s WHERE s.key1 = 1",
    None,
    select_json_params,
)
print(result.read())
bucket.delete_object(key)

# --- JSON LINES クエリ ---

key = "python_select_lines.json"
content = '{"key1":1,"key2":"hello world1"}\n{"key1":2,"key2":"hello world2"}'
bucket.put_object(key, content)

select_json_params = {"Json_Type": "LINES"}
json_header = bucket.create_select_object_meta(key, select_json_params)
print(f"Total rows: {json_header.rows}, total splits: {json_header.splits}")

result = bucket.select_object(
    key, "SELECT s.key2 FROM ossobject s WHERE s.key1 = 1", None, select_json_params
)
print(result.read())
bucket.delete_object(key)

OSS API を使用したオブジェクトのクエリ実行

RESTful API を直接使用して SelectObject を呼び出す場合、署名計算をコードに組み込む必要があります。詳細については、「SelectObject」をご参照ください。

ラージオブジェクトに対する並列クエリの実行

ラージオブジェクトに対しては、split-range を使用して、複数の同時実行リクエストにクエリを分割します。

分割(split)とバイト範囲(byte range)の使い分け:

方法使用タイミング
分割単位(推奨)分割は複数の行を含み、おおよそ均等なサイズになります。JSON オブジェクトおよび列値に改行を含む可能性のある CSV オブジェクトに使用します。
バイト範囲単位シンプルですが、メタデータは不要です。列値に改行を含まない CSV オブジェクトにのみ使用します。

分割単位の並列クエリの手順:

  1. 分割数の合計値を取得するために CreateSelectObjectMeta を呼び出します。最初のクエリ実行前に非同期で呼び出すことで、余分なスキャンオーバーヘッドを回避できます。

  2. 利用可能なクライアントリソースに基づいて、同時実行数 n を決定します。

  3. 分割数の合計値を n で割って、1 回のリクエストあたりの分割数を算出します。

  4. n 個の同時実行 SelectObject リクエストを送信します。各リクエストには split-range パラメーターを指定します。例:split-range=1-20

  5. 結果を順序通りに結合します。

次のステップ