Как измерить объем пространства, занимаемого blobs в базе данных Firebird 2.1?

У меня есть производственная база данных, использующая Firebird 2.1, где мне нужно узнать, сколько места используется каждой таблицей, включая blobs. Blob-часть является сложной, потому что она не покрывается с помощью стандартного статистического отчета.

У меня нет легкого доступа к рабочему столу сервера, поэтому установка UDFs и т. д. это не лучшее решение.

Как я могу сделать это легко?

2 ответов


вы можете подсчитать общий размер всех полей BLOB в базе данных со следующей инструкцией:

EXECUTE BLOCK RETURNS (BLOB_SIZE BIGINT)
AS
  DECLARE VARIABLE RN CHAR(31) CHARACTER SET UNICODE_FSS;
  DECLARE VARIABLE FN CHAR(31) CHARACTER SET UNICODE_FSS;
  DECLARE VARIABLE S BIGINT;
BEGIN
  BLOB_SIZE = 0;
  FOR
    SELECT r.rdb$relation_name, r.rdb$field_name 
      FROM rdb$relation_fields r JOIN rdb$fields f 
        ON r.rdb$field_source = f.rdb$field_name
    WHERE f.rdb$field_type = 261
    INTO :RN, :FN
  DO BEGIN
    EXECUTE STATEMENT
      'SELECT SUM(OCTET_LENGTH(' || :FN || ')) FROM ' || :RN ||
      ' WHERE NOT ' || :FN || ' IS NULL'
    INTO :S;
    BLOB_SIZE = :BLOB_SIZE + COALESCE(:S, 0);
  END
  SUSPEND;
END

Я изменил пример кода Andrej, чтобы показать размер каждого поля blob, а не только сумму всех Blob.

и используется термин SET, поэтому вы можете скопировать и вставить этот фрагмент непосредственно в инструменты, такие как FlameRobin.

SET TERM #;
EXECUTE BLOCK
RETURNS (BLOB_SIZE BIGINT, TABLENAME CHAR(31), FIELDNAME CHAR(31) )
AS
  DECLARE VARIABLE RN CHAR(31) CHARACTER SET UNICODE_FSS;
  DECLARE VARIABLE FN CHAR(31) CHARACTER SET UNICODE_FSS;
  DECLARE VARIABLE S BIGINT;
BEGIN
  BLOB_SIZE = 0;
  FOR
    SELECT r.rdb$relation_name, r.rdb$field_name 
      FROM rdb$relation_fields r JOIN rdb$fields f 
        ON r.rdb$field_source = f.rdb$field_name
    WHERE f.rdb$field_type = 261
    INTO :RN, :FN
  DO BEGIN
    EXECUTE STATEMENT
      'SELECT SUM(OCTET_LENGTH(' || :FN || ')) AS BLOB_SIZE, ''' || :RN || ''', ''' || :FN || '''
      FROM ' || :RN ||
      ' WHERE NOT ' || :FN || ' IS NULL'
    INTO :BLOB_SIZE, :TABLENAME, :FIELDNAME;
    SUSPEND;
  END
END
#
SET TERM ;#

этот пример не работает с ORDER BY, возможно, существует более элегантное решение без блока EXECUTE.