PDA

View Full Version : DDS: VARLEN, SQL TRIM -> trotzdem große Datei



schatte
01-02-12, 21:14
Hallo Leute,

ich versuche mich gerade mit dem DDS Schlüsselwort VARLEN, um bei einem Feld mit 2048 Zeichen Platz zu sparen.

Zum Größenvergleich habe ich daher folgende Dateien erstellt:
PCHAR:

A R PCHARF
A*
A CHTEXT 2048A COLHDG('CHAR')


PCHARVAR:

A R PCHARF
A*
A CHTEXT 2048A COLHDG('VARCHAR')
A VARLEN


Anschließend befülle ich beide Dateien mit jeweils folgenden SQL Befehlen:

INSERT INTO SPEED/PCHAR
VALUES('0123456789012345678901234567890123456789')
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR
INSERT INTO SPEED/PCHAR


Dadurch habe ich in jeder Datei 4096 Sätze. Anschließend noch ein RGZPFM auf jede Datei.

Größen der Dateien (Dieses Ergebnis würde ich auch erwarten):
PCHAR: 8.400.896
PCHARVAR: 335.872

Wenn ich aber nun alle Datensätze der Datei PCHAR per CPYF in die Datei PCHARVAR kopiere (CPYF FROMFILE(SPEED/PCHAR) TOFILE(SPEED/PCHARVAR) MBROPT(*REPLACE) FMTOPT(
*MAP)), hat die Datei PCHARVAR folgende Größe:
9.510.912

Auch das ist in Ordnung, da ja nun auch die ganzen SPACES am Feldende enthalten sind.

Wenn ich aber nun per SQL das Feld CHTEXT der Datei PCHARVAR per RTRIM aktualisiere, hätte ich erwartet, dass auch die Datei entsprechend wieder kleiner wird.
Das SQL Statement:
UPDATE SPEED/PCHARVAR SET CHTEXT = rtrim(CHTEXT)

Die Dateigröße ist nun sogar noch größer geworden:
9.547.776

Auch ein RGZPFM bringt nicht meine erwartete Größe von 335.872 Byte.

Was habe ich falsch gemacht?

Viele Grüße
Matthias

andreaspr@aon.at
02-02-12, 08:24
Hallo,

mit VARLEN werden die Werte außerhalb der Tabelle gespeichert. In der Spalte wird dann via Pointer auf diesen Speicherbereich verwiesen.

Normal gibst du jedoch aus Gründen der Performance bei VARLEN noch die Anzahl an Bytes an, sodass der Wert (solang er die Grenze nicht überschreitet) noch im Tabellenspeicher hinterlegt werden kann.
Üblicher weise verwendet man dafür die am meisten verwendete Länge.


A R PCHARF
A*
A CHTEXT 2048A COLHDG('VARCHAR')
A VARLEN(50)


Vielleicht macht das einen Unterschied?

lg Andreas

Pikachu
02-02-12, 08:46
Ich würde mal sagen, du hast nichts falsch gemacht.

Hier ist ein ähnlicher Fall:

CPYF - Size Difference in Results Using NBRRCDS versus FROMRCD and TORCD (https://www-304.ibm.com/support/docview.wss?uid=nas1212aef1b8221342686256c0d004ea7 98)

Fuerchau
02-02-12, 09:12
Das Problem ist tatsächlich, dass der separate Varlen-Bereich nichts mit dem RGZPFM zu tun hat.
Dieser Bereich wird intern verwaltet und aus dem Satz verpointert.
Der RGZPFM entfernt halt nur gelöschte Sätze und schiebt den Bereich dann zusammen, wobei die Verpointerung erhalten bleibt.
Der Varlen-Bereich kann natürlich auch zu großen Lücken führen (ähnlich zu Memory-Leaks), wenn häufig Varlen-Felder geändert werden und in den damit freien Bereichen keine passende Größe gefunden wird.
Kleiner bekommt man diese tatsächlich nur per CPYF, allerdings nur wenn man die Anzahl Sätze (siehe obiger Link) dann mit angibt.

Alternativ geht es dann auch per SQL (in etwa so):
create mynewtable as
select * from myoldtable
with data

Was mir allerdings bei den Indizes nicht so hilft.

Beim Erstaufbau aus Altdaten ist der
insert into MyNewFile
select ..., rtrim(fx), ...
from MyOldFile
zu empfehlen.

schatte
02-02-12, 11:54
Ich würde mal sagen, du hast nichts falsch gemacht.

Hier ist ein ähnlicher Fall:

CPYF - Size Difference in Results Using NBRRCDS versus FROMRCD and TORCD (https://www-304.ibm.com/support/docview.wss?uid=nas1212aef1b8221342686256c0d004ea7 98)

Das wusste ich ja noch garnicht.

Ich habe gerade auch mal versucht, die Datei PVARCHAR (9MB groß) in eine neue Datei mit gleichem Aufbau (also auch VARLEN) per CPYF zu kopieren.
Diese neue Datei hat nun auch die erwartete Dateigröße von ein paar 100kb, statt 9MB.

Eigentlich könnte die IBM doch schön einen neuen OS/400 Befehl erstellen, mit dem solche Dateien "defragmentiert" würden.

Vielen für eure Antworten.

Gruß
Matthias

Fuerchau
02-02-12, 12:23
Warum einen neuen, wenn es doch SQL gibt?

Pikachu
02-02-12, 12:30
Mit SQL geht's leider auch nicht:


Wenn ich aber nun per SQL das Feld CHTEXT der Datei PCHARVAR per RTRIM aktualisiere, hätte ich erwartet, dass auch die Datei entsprechend wieder kleiner wird.
Das SQL Statement:
UPDATE SPEED/PCHARVAR SET CHTEXT = rtrim(CHTEXT)

Die Dateigröße ist nun sogar noch größer geworden:
9.547.776

Fuerchau
02-02-12, 12:54
Ein Update bereinigt ja nie die Dateigröße. Es weden nur im Varlenbereich Plätze freigegeben und neu belegt, das ist im Prinzip das gleiche wie REUSEDLT(*YES), bei SQL-tables default, da wird die Datei ja auch nicht kleiner.

Eine Reorg geht eben nur per SQL mit "Insert ... Select", den man ggf. halt 2 Mal machen muss (hin und zurück nach CLRPFM) oder die Indizes/Views usw. auf die neue Tabelle umstellt.