2014-12-11 11 views
6

Korzystając z PostgreSQL 9.4 mamy prostą tabelę kontaktów z (tekstem id nie null (jak pk), blob json) do eksperymentowania z portowaniem bazy danych couchdb crm. W końcu podzielimy się na więcej kolumn itd., A dane będą przetwarzane bardziej idomatycznie dla rdbms, ale na razie jest to poza tym punktem.Postgresql Offset Behavior z kolumną json

Istnieje około 100 tys. Wierszy.

Zdaję sobie sprawę, że eksperci skuteczności Hardcore postgresql odradzam offsetowego jednak mogę zaakceptować niewielką karę wydajności (szczęśliwy z niczego mocy 100 ms)

SELECT id FROM couchcontacts OFFSET 10000 LIMIT 10 

Jak oczekiwano trwa < 10ms

SELECT blob->>'firstName' FROM couchcontacts LIMIT 10 

Zajmuje także < 10ms (przyjmuj 10 błędów dekodowania json na kolumnie blob tutaj)

SELECT blob->>'firstName' FROM couchcontacts OFFSET 10000 LIMIT 10 

Trwa w górę z 10 sekund !! Zauważalne są nieefektywności przesunięcia na bok, dlaczego to prawdopodobnie powoduje 10 010 dekodowania jsonów? Ponieważ projekcja nie ma skutków ubocznych, nie rozumiem powodu, dla którego to nie może być szybkie?

Czy to ograniczenie funkcji json jest względnie nowe w postgresie? i w ten sposób niezdolny do określenia openeratora ->> nie powoduje skutków ubocznych?

Ciekawe przepisywania zapytań do tego doprowadzić go z powrotem pod 10milliseconds

SELECT jsonblob->>'firstName' FROM couchdbcontacts WHERE id IN (SELECT id FROM couchcontacts OFFSET 10000 LIMIT 10) 

Czy istnieje sposób, aby zapewnić przesunięcie robi json dekodowania offsetted rekordy? (tj. nie wykonuj projekcji select)

"Limit (cost=1680.31..1681.99 rows=10 width=32) (actual time=12634.674..12634.842 rows=10 loops=1)" 
" -> Seq Scan on couchcontacts (cost=0.00..17186.53 rows=102282 width=32) (actual time=0.088..12629.401 rows=10010 loops=1)" 
"Planning time: 0.194 ms" 
"Execution time: 12634.895 ms" 
+0

To wygląda jak szorstki zakątek tej nowej funkcji. Proszę zgłosić to jako błąd do PostgreSQL. Domyślam się, że obejście to jest ręcznym przywołaniem, tak jak pokazałeś się. – Thilo

+1

"WYJAŚNIJ ANALIZĘ", proszę? Nie jestem całkowicie przekonany wyjaśnieniem rozbieżności. Czy stworzyłeś profil/'perf top'/etc, aby sprawdzić, czy twoje hipotetyczne wyjaśnienie pasuje do zaobserwowanego zachowania? Choć w mgnieniu oka ... Myślę, że jeśli poprosisz o zestaw wyników z przesunięciem, PostgreSQL powinien oceniać wyrażenia w odrzuconych wierszach, chyba że może udowodnić, że nie mają żadnych skutków ubocznych. Więc może to jest ocena wyrażeń json ... i prawdopodobnie powinno to być, chyba że może udowodnić, że nie mogą przerwać zapytania z 'ERROR' lub zmienić stan bazy danych. –

+0

Biorąc pod uwagę - >> jest wbudowany operator, nie powinien postgresql wiedzieć, że to nie powoduje skutków ubocznych? czy istnieje sposób na wskazówkę, że to nie powoduje efektu ubocznego? Zaktualizowano analizując objaśnienia –

Odpowiedz

5

Przeprowadziłem kilka testów i widzę podobne zachowania. Każdy z nich ma nieistotnych różnic w wydajności:

  • select id ...
  • select indexed_field ...
  • select unindexed_field ...
  • select json_field ...
  • select * ...

Ten pokazuje jednak różnicę w wydajności:

  • select json_field->>'key' ...

Gdy json_field jest zerowy wpływ wydajność jest znikoma. Kiedy jest pusty, degraduje rzeczy bardzo nieznacznie. Kiedy jest wypełniony, degraduje się zauważalnie. A gdy pole zostanie załadowane większymi danymi, degraduje się materialnie.

Innymi słowy, Postgres wydaje się chcieć odserializować dane json dla każdego odwiedzanego wiersza. (Co jest prawdopodobnie błędem i ma ogromny wpływ na programistów RoR, którzy widzą, jak używają json.)

FWIW, zauważył, że re-aranżacji zapytanie więc używa CTE będzie obejść ten problem:

with data as (
    select * from table offset 10000 limit 10 
) 
select json_field->>'key' from data; 

(To może otrzymać tylko-bardzo-nieco lepszy plan niż zapytania id IN (...) że podświetlone.)

+0

Dzięki za testy. Dodajemy, że nie używamy RoR, ale Clojure, ponieważ wielu programistów teraz naciska Postgres jako zamiennik NoSQL (blogi, konferencje, microbenchmarks). Na pewno te scenariusze staną się bardziej powszechne w wielu stosach. –

+1

Tak. Na wszelki wypadek poświęć chwilę, aby zgłosić problem do pg-performance lub listy pg-bugs. Domyślam się, że jest to niedopatrzenie w bazie kodu: różne funkcje JSONA związane z czytaniem są niezmienne, o ile mogę to stwierdzić, więc nie widzę powodu, aby zawracać sobie głowę oceną ich podczas odrzucania wierszy. –

+0

Zgłosiłem zgłoszenia do pg-bugs i poczekam, aby zobaczyć, co się stanie (jest to lista moderowana). Zostawię to zaznaczone jako nieodebrane na dzień lub dwa z powodu dziwnego powodu, który jest zgodny z projektem. –