2012-04-16 4 views
9

ブロブのバイトサイズを取得したいと思います。PostgreSQLのクエリで大きなオブジェクトのサイズを取得しますか?

私はPostgresqlを使用しており、SQLクエリを使用してサイズを取得したいと考えています。このようなもの:

SELECT sizeof(field) FROM table; 

これはPostgreSQLで可能ですか?

更新:私はpostgresqlのマニュアルを読んだので、ファイルサイズを計算するのに適切な関数が見つかりませんでした。また、ブロブはラージオブジェクトとして格納されます。

+0

を、このような質問を投稿する前に取扱説明書をよくお読みください:http://www.postgresql.org/docs/current/static/functions.html –

+2

は「BLOBデータの定義"バイトカット '?または 'pg_largeobject'に格納された大きなオブジェクトですか?テーブル定義を表示します。 –

+0

[PostgreSQLのオブジェクトのサイズを取得する]の複製(http://stackoverflow.com/questions/9248738/obailable-the-size-of-lobject-in-postgressql)? –

答えて

12

を試してみてください、しかし、ドキュメントを見て:http://www.postgresql.org/docs/current/interactive/lo-interfaces.html#LO-TELL

は、私はあなたには、いくつかのファイルシステムAPIが必要と同じ技術を使用しなければならないと思う:へのシーク最後に、位置を教えてください。 PostgreSQLには、内部のC関数をラップするように見えるSQL関数があります。私は多くのドキュメントを見つけることができませんでしたが、これは働いていた:

CREATE OR REPLACE FUNCTION get_lo_size(oid) RETURNS bigint 
VOLATILE STRICT 
LANGUAGE 'plpgsql' 
AS $$ 
DECLARE 
    fd integer; 
    sz bigint; 
BEGIN 
    -- Open the LO; N.B. it needs to be in a transaction otherwise it will close immediately. 
    -- Luckily a function invocation makes its own transaction if necessary. 
    -- The mode x'40000'::int corresponds to the PostgreSQL LO mode INV_READ = 0x40000. 
    fd := lo_open($1, x'40000'::int); 
    -- Seek to the end. 2 = SEEK_END. 
    PERFORM lo_lseek(fd, 0, 2); 
    -- Fetch the current file position; since we're at the end, this is the size. 
    sz := lo_tell(fd); 
    -- Remember to close it, since the function may be called as part of a larger transaction. 
    PERFORM lo_close(fd); 
    -- Return the size. 
    RETURN sz; 
END; 
$$; 

テストそれ:

-- Make a new LO, returns an OID e.g. 1234567 
SELECT lo_create(0); 

-- Populate it with data somehow 
... 

-- Get the length. 
SELECT get_lo_size(1234567); 

LO機能は、主にクライアントを介して、または低レベルのサーバープログラミングを介して使用するように設計されているようです少なくとも、SQL可視関数を提供しているので、上記のことが可能になります。私は自分自身を開始するためにSELECT relname FROM pg_proc where relname LIKE 'lo%'の質問をしました。プログラミングの曖昧な思い出と、残りのためには、x'40000'::intSEEK_END = 2という値の研究が必要でした。

3

私は大規模なオブジェクトを使用したことはないlength()またはoctet_length()

10

ラージオブジェクトの作成時にサイズを保存するようにアプリケーションを変更することができます。あなたは以前の記事で示唆したように、彼らは[OK]を動作しますが、上記の提案を選択する方法よりも遅く一桁、また、ラージオブジェクトAPI関数を使用することができ

select sum(length(lo.data)) from pg_largeobject lo 
where lo.loid=XXXXXX 

:そうしないと次のようなクエリを使用することができます。

+0

これは最もクリーンなソリューションです。 Thanks – MarekM

+1

残念ながら、PostgreSQL 9.0以降、 'pg_largeobject'カタログは公にアクセスできなくなりました。https://www.postgresql.org/docs/current/static/catalog-pg-largeobject.html。 – ochedru

4
select pg_column_size(lo_get(lo_oid)) from table; 

サイズをバイト単位で指定します。

あなたはかなり印刷したい場合:

select pg_size_pretty(pg_column_size(lo_get(lo_oid))::numeric) from table; 
関連する問題