currval i problemy z selectami

jak może wiecie w postgresie jest funkcja currval() zwracająca ostatnio nadane id z podanej sekwencji.

rozpatrzmy prosty przypadek:

# create table test (id serial primary key, pole int4);
CREATE TABLE
# insert into test (pole) select * from generate_series(1, 10000);
INSERT 0 10000
# select count(*) from test;
 count
-------
 10000
(1 row)
# select currval('test_id_seq');
 currval
---------
   10000
(1 row)

wszystko wygląda ok. więc sprawdźmy jeszcze jeden insert mały:

# insert into test(pole) values (12313);
INSERT 0 1
# select currval('test_id_seq');
 currval
---------
   10001
(1 row)

nadal wszystko ok. i teraz:

# select * from test where id = currval('test_id_seq');
  id   | pole
-------+-------
 10001 | 12313
(1 row)
Time: 93.358 ms

działa, ale coś wolno, sprawdźmy:

# explain analyze select * from test where id = currval('test_id_seq');
                                            QUERY PLAN
--------------------------------------------------------------------------------------------------
 Seq Scan on test  (cost=0.00..200.02 rows=1 width=8) (actual time=64.375..64.379 rows=1 loops=1)
   Filter: (id = currval('test_id_seq'::regclass))
 Total runtime: 64.431 ms
(3 rows)

seq scan? sprawdźmy więc ręcznie podaną wartość:

# explain analyze select * from test where id = 10001;
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Index Scan using test_pkey on test  (cost=0.00..8.02 rows=1 width=8) (actual time=0.029..0.033 rows=1 loops=1)
   Index Cond: (id = 10001)
 Total runtime: 0.086 ms
(3 rows)

hmm .. tu jest dobrze. skąd seq scan? aby nie przynudzać z każdym zapytaniem, powiem tyle, że nie jest to kwestia błędnych typów czy czegoś tak oczywistego. problemem jest zmienność funkcji.

dokładniej: funkcja currval() jest zadeklarowana jako “volatile" – co oznacza, że jej wynik ma prawo zmienić się w czasie pojedynczego skanu tabeli. tak jak np. random(). to oznacza, że nie można użyć jej jako dostarczyciela wartości i potem tą wartością przeszukać indeksy.

cóż więc można zrobić – no cóż. trzeba powiedzieć postgresowi, że interesuje nas tylko pierwsza zwrócona wartość currvala – idealnie do tego nadają się podzapytania:

# explain analyze select * from test where id = (select currval('test_id_seq'));
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Index Scan using test_pkey on test  (cost=0.01..8.03 rows=1 width=8) (actual time=0.047..0.050 rows=1 loops=1)
   Index Cond: (id = $0)
   InitPlan
     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.010..0.012 rows=1 loops=1)
 Total runtime: 0.187 ms
(5 rows)

jak widać jest już zdecydowanie lepiej.

ile jest wart postgres

dziś jest dzień postgresql'owy, więc kolejna informacja o nim.

jest taki program: sloccount. służy do liczenia ilości linii kodu, oraz estymowaniu kosztów stworzenia programu.

odpaliłem go na źródłach postgresa 8.2. oto wynik:

Totals grouped by language (dominant language first):
ansic:       479298 (94.01%)
yacc:         14698 (2.88%)
sh:            7805 (1.53%)
lex:           5349 (1.05%)
perl:          2608 (0.51%)
asm:             65 (0.01%)
python:          12 (0.00%)
<br/>
Total Physical Source Lines of Code (SLOC)                = 509,835
Development Effort Estimate, Person-Years (Person-Months) = 139.26 (1,671.14)
 (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
Schedule Estimate, Years (Months)                         = 3.50 (41.95)
 (Basic COCOMO model, Months = 2.5 * (person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule)  = 39.84
Total Estimated Cost to Develop                           = $ 18,812,337
 (average salary = $56,286/year, overhead = 2.40).
SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.
SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to
redistribute it under certain conditions as specified by the GNU GPL license;
see the documentation for details.
Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."

pl/scheme

(hurra, (dzięki (projektowi (pl/scheme))) (wreszcie) (będziemy (się (mogli))) (w postgresie) (cieszyć (z kodu (składającego się (z samych (nawiasów)))))) 🙂

funkcje ułatwiające migracje z oracle’a

przeczytałem właśnie o interesującym module – orafce. moduł ten zawiera ponad 100 funkcji których celem jest emulowanie funkcji bazodanowych z oracle'a i plvision (taki pakiet do oracle'a).

funkcje w orafce są kompatybilne na poziomie api z wersjami z oracle'a co powoduje, że ich użycie mocno uprości ewentualną migrację między tymi platformami.

wśród funkcji zawartych w pakiecie są m.in.:

  • kilka funkcji podstawowych – typu next_day, last_day
  • funkcje kalendarza biznesowego – bazujące na pakiecie plvdate z plvision
  • spory zestaw funkcji do pracy na stringach
  • obsługa komunikacji między procesowej

zwrócić należy uwagę na fakt iż nie ma w tym pakiecie niczego czego nie dałoby się uzyskać w postgresie inaczej – jednakże sensem istnienia tego pakietu nie jest dodawanie funkcjonalności, a ułatwianie migracji.

nowości w postgresie 8.2 – … advisory locks

miałem o tym napisać później, ale skoro merlin już opisał advisory locki, nie pozostaje mi nic innego niż
opisać je u siebie.

advisory locki są to zupełnie nowe locki nie powiązane z żadnymi fizycznymi obiektami w bazie. służą one do
przekazywania informacji między sesjami i transakcjami.

najbardziej szczególną cechą tych locków jest to, że działają poza mechanizmem transakcji. dzięki temu możliwe jest używanie
ich do celów do których standardowe locki sie nie nadawały.

przykładem użycia z mojego podwórka jest zakładanie locka na konkretne źródło rss'ów w dnewsach. do tej pory musiałem mieć
oddzielną tabelkę i w niej trzymać wpisy. do tego dochodziły kwestie czyszczenia wpisów gdyby program ściągający dane padł i nie
skasował swojego locka.

z drugiej strony – mogłem uzyć locków wewnątrz transakcji, ale to by oznaczało trzymanie długo trwających transakcji – a one z
definicji są złe (psują systemy replikacyjne).

advisory locki robią to co trzeba.

sesja (połącznie) które potrzebuje zakłada locka (locka zakłada sie na “liczbę" z zakresu int8, albo na parę liczb int4). lock
zostaje zdjęty gdy wywołam funkcję zdejmującą lub gdy padnie połączenie!

advisory locki są trzymane w pamięci dzięki czemu są baaaaaardzo szybkie – merlin przeprowadził prosty test zakładając 1000
advisory locków w około 6 milisekund!

dodatkowo – dzięki temu, że są trzymane w pamięci – odpadaję wszelkie bolączki mvcc – puchnące tabele, wolny odczyt,
vacuumowanie itd. advisory locki są błyskawiczne i całkowicie bezpieczne.

przykładowe użycie:

# select pg_advisory_lock(123);<br/>
 pg_advisory_lock<br/>
------------------<br/>
''<br/>
(1 row)<br/>
# select pg_advisory_unlock(123);<br/>
 pg_advisory_unlock<br/>
--------------------<br/>
 t<br/>
(1 row)

oczywiście advisory locki zapewniają wszystkie standardowe metody dostępu:

  • pobranie locka blokujące
  • pobranie nieblokujące
  • locki exclusive
  • locki shared

polecam przyjrzenie
się tej funkcjonalności – ma ona sporo niecałkiem oczywistych zastosowań.

ciąd dalszy wywiadu z bjornem stroustrupem

na mit technology review pojawiła się druga część wywiadu z twórcą c++.

tym razem mówi o przyszłości, trendach, przykładach świetnego kodu, o tym czy i co zastąpi programowanie obiektowe oraz o tym czy .net jest spadkobiercą c++ 🙂

warto przeczytać.

zdrowa coca-cola

w 2007 roku coca-cola ma wypuścić nowy napój – diet coke plus.

napój ten będzie bazował na diet coke (coca-cola light), ale będzie dodatkowo wzbogacany o witaminy i minerały.

czy to oznacza, że koncern chce walczyć z wizerunkiem niezdrowej, szkodliwej coli? tylko co ze smakiem?

pepsi ma wypuścić odpowiedź – napój o nazwie tava rok później.

jedzenie tłuszczu nielegalne?

władze nowego jorku zdelegalizowały używanie tzw. “trans fats" (tłuszczy jakichś tam, ogólnie – zwierzęce, niezdrowe).

z jednej strony ok – tłuszcze te (może ktoś mi podpowie jak to się tłumaczy na polski) są niezdrowe, prowadzą do kupy chorób. ale, kurza wasza melodia, to moje prawo żreć co chcę.

wygląda na to, że władza tamże uznała, że mieszkańcy są tak głupi, że nie potrafią podjąć świadomej decyzji o tym co zjedzą (nota bene pewnie mają rację). problemem jest to, że takie ubezwłasnowolnienie ma kupę wad:

  • powoduje, że od groma ludzi nagle stanie się przestępcami – wystarczy przygotowanie foie gras.
  • zwalnia ludzi od myślenia
  • wchodzi z butami z prywatne życie prywatnych ludzi
  • jest prawem martwym – nikt normalny nie będzie się tym przejmował – tak jak np. limitami prędkości. tzn. do czasu aż pojawią się bojówki i będzie wydany pierwszy wyrok – śmierć przez powieszenie za podanie klientowi kotleta smażonego na smalcu.

ci co mnie znają, wiedzą, że ogólnie stany mi się podobają. wiem, że mają swoje problemy, ale po prostu podoba mi się ten kraj (niestety nie byłem). i wiem, że jest przynajmniej kilka osób które potraktują tę informację jako wyraz starczej demencji. zdarza się. ale nawet ja – lubiący amerykę – nie potrafię zrozumieć czym się kierowały elity polityczne uchwalając taką bzdurę.