Binäre Daten von max 30 Bytes einfügen

16 Bytes, nicht 8 Bytes. Durch TEXT und ByteA entsteht ein Overhead.

Allerdings bringen dir die Operationen auch nur etwas, wenn du direkt in der DB danach suchen kannst - und vernünftig mit einem Index lassen die sich nicht beschleunigen.

warum nicht? es gibt doch sicher eine handvoll fragen - die sich auf ein paar bits beziehen - ueber die man die datenmenge recht grob einschraenken kann … fuer die wuerde ich mir nen index bauen … wenn eine frage z.B. 4 od. mehr bits betrifft, dann dann kann man die ja ueber shift operationen etc- zusammenfuehren … das ergibt dann eine zahl … mit ausreichend granularitaet

wichtig ist, dass im where - od. wo auch immer - der gleiche ausdruck steht, wie der wo der index erzeugt wurde … ne funktion waere dafuer bestens geeignet - damit man spaeter nicht viel schreiben muss und sowieso und ueberhaupt

Weil du dann durch die vielen notwendigen Indexe einen Haufen Speicherplatz und - noch wichtiger - Schreibperformance verlierst.
Dafür müssen die Bitoperationen schon sehr davon profitieren, damit sich das lohnt.

Letztendlich: austesten.
Ich glaube aber nicht dran.

plattenspeicher ist billig

schreibperformance ist ein argument … aber komm schon … so schlecht ist pg da auch nicht :slight_smile:

aber ja - nicht glauben - testen

wegen einem bit wuerde ich das auch nicht machen …

Wenn ich das richtig in Erinnerung habe, brauchst du pro möglichem Bit einen funktionalen Index. Sprich, bei 5 Bits sind das 5 verschiedene Indexe.

Das macht also die 6-fache Schreiblast (1x Daten, 5x Index).
Das rechnet sich irgendwann nicht mehr.

nee so mein ich das nicht …

nehmen wir an bei einer frage spielen 3 bits eine rolle

dann schreibe ich mir eine funktion die mir die entsprechenden bits von x1xxx1xxxx1 nach 00000111 shiftet …

 index_val = f(bla_flags, blub_flags, ... )

mit dieser funktion erzeuge ich mir nen index …

 create index ... on .. f(bla_flags, blub_flags, ... )

und die funktion nehme ich auch in meinen abfragen …

 select .. where b'101' = f(bla_flags, blub_flags, ... )

oder sowas sollte doch dank bitmat-index scan funktionalitaet auch gehen … was meinst du

 select .. where (b'100' & f(bla_flags, blub_flags, ... ))::Boolean

freilich - ein bisschen drueber nachdenken, wonach man so sucht sollte man auch hier - macht man ja auch sonst bei der wahl von indices …

gut, was ich jetzt nicht weiss ist - wie schnell die bitoperationen selbst sind … also in der funktion … so ein shift mit << od >> bzw. das & | # usw. aber mit bits hantieren ist doch das, was ein rechner so macht … das sollte unproblematisch sein

So, und jetzt wirf das alles mal in ein EXPLAIN, dann reden wir weiter.

bis auf den 4. code bin ich mir sicher dass es funktioniert … was die funktion intern macht muss pg doch garnicht wissen um zu erkennen dass der ausdruck fuer den index passt …

Wie gesagt, probier es aus.
Natürlich geht das - unter gewissen Umständen.

CREATE TABLE bits
(
  a smallint,
  b smallint,
  c integer
)



CREATE OR REPLACE FUNCTION bshift(a smallint, b smallint, c integer)
  RETURNS integer AS
$BODY$
BEGIN
	return 0;
END
$BODY$
  LANGUAGE 'plpgsql' IMMUTABLE
  COST 1;

CREATE INDEX idx_bits
  ON bits
  USING btree
  (bshift(a, b, c));



set enable_seqscan=off;
explain analyse select * from bits where b'0111'::int = bshift(a,b,c)



"Bitmap Heap Scan on bits  (cost=4.34..15.04 rows=11 width=8) (actual time=0.011..0.011 rows=0 loops=1)"
"  Recheck Cond: (7 = bshift(a, b, c))"
"  ->  Bitmap Index Scan on idx_bits  (cost=0.00..4.34 rows=11 width=0) (actual time=0.005..0.005 rows=0 loops=1)"
"        Index Cond: (7 = bshift(a, b, c))"
"Total runtime: 0.047 ms"

mit & als beispiel der bitoperationen geht natuerlich nicht (so einfach) - sicher wegen dem gewaehlten operator … da muesste man sich dann entsprechend tiefer mit pg indices beschaeftigen …

Nun, das kommt, weil du deine Funktion immutable deklariert hast und die Kosten für eine plpgsql Funktion sehr niedrig ansetzt. PostgreSQL selbst nimmt 100 für alle Funktionen an, die nicht in C geschrieben sind.

Es geht hier aber nicht darum, Bits durch die Gegend zu shiften (dabei hilft eine immutable Funktion) sondern es geht darum, bestimmte gesetzte Bits mit Hilfe eines Index zu erkennen. Dafür brauchst du keine extra Funktion, aber du brauchst einen Index pro Aufruf - also in der Regel pro Bit Ergebnis.

Versuch doch mal, deinen Index für alle Anfragen zu nutzen. Also egal, ob ich das 3. oder das 7. Bit - oder auch beide - gesetzt suche.

das koennte man doch durch zb

bshift() > b’0000100’ and / or bshift() < b’0000011’

bshift() in (b’0000100’, b’0000101’, … )

usw. erreichen

so schnell geb ich nicht auf :wink:

Und so weiter und so fort. Natürlich kann man das erreichen.
Das muss man auch alles in den Index schreiben.

Sprich, entweder du hast alle möglichen Fragekombinationen schon irgendwie im Index stehen oder du hast pro Kombination einen getrennten Index.
Schön wird das alles zum Schluß nicht mehr, auch wenn ich die ganze Zeit gesagt habe, dass das funktioniert.

Natürlich seh ich die Probleme auch … hat alles seine Grenzen