niesamowity stół

dzięki koledze z pracy zobaczyłem niesamowity stół. co prawda jest on przeznaczony do instalacji na łodziach, jest drogi i nie stać mnie na niego. a na stronie producenta jest informacja:

Please understand that this is an extremely special piece of furniture, of exceptional quality and design – it is not for everyone by a very very long way and can only be afforded by the lucky few of us with exceptional wealth.

to i tak strasznie mi się podoba. kiedyś go sobie kupię 🙂

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.