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.
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
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
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