2013-06-14 13 views
22

Redshift umożliwia oznaczanie wielu kolumn jako kolumn SORTKEY, ale większość dokumentacji dotyczącej najlepszych praktyk jest napisana tak, jakby istniał tylko jeden SORTKEY.Co to znaczy mieć wiele kolumn sortkey?

Jeśli utworzę tabelę z SORTKEY (COL1, COL2), czy to oznacza, że ​​wszystkie kolumny są przechowywane posortowane według COL1, a następnie COL2? A może, ponieważ jest to magazyn kolumnowy, każda kolumna zostaje zapisana w innej kolejności? To znaczy. COL1 w porządku COL1, COL2 w porządku COL2, a pozostałe kolumny nieuporządkowane?

Moja sytuacja polega na tym, że mam tabelę z (między innymi) kolumną type_id i timestamp. Dane przybywają z grubsza w kolejności znaczników czasu. Większość zapytań łączy się z/ogranicza zarówno typ_id, jak i znacznik czasu. Zwykle klauzule type_id są bardziej szczegółowe, co oznacza, że ​​znacznie większy procent wierszy można wykluczyć, patrząc na klauzulę type_id, niż patrząc na klauzulę timestamp. type_id to DISTKEY z tego powodu. Próbuję zrozumieć zalety i wady: SORTKEY (type_id), SORTKEY (stamp), SORTKEY (type_id,stamp), SORTKEY (stamp,type_id).

Dzięki.

+0

Jeśli chcesz, aby twoje wyniki były posortowane według więcej niż jednej kolumny (ORRDER BY 1.2.3 ...), posortuj odpowiednio dane. – Guy

Odpowiedz

14

Jeśli zadeklarujesz , wszystkie kolumny zostaną posortowane według COL1, a następnie COL2 tak, jakby wykonano ORDER BY (COL1, COL2).

Jeśli używasz SORTKEY przyspieszyć JOIN, AFAIU nie ma znaczenia, tak długo, jak korzystać z tego samego SORTKEY na stołach, które zostaną połączone z powodu tego, co się dzieje, jest scalanie przyłączyć.

Jeśli COL1 jest wysoce selektywny, tak jak Twój type_id, oznacza to, że istnieje tylko niewielka liczba rzędów o tym samym numerze type_id. Dlatego chociaż możesz dodać kolejną kolumnę do SORTKEY, jej użyteczność jest ograniczona, ponieważ większość eliminacji wierszy już się wydarzyła.

Jeśli COL1 nie jest wysoce selektywny jak twój stamp (co jest nieco dziwne btw;? Liczyłam, że jest bardziej selektywny niż type_id Anyways ..), oznacza to, że filtrowanie przez stamp nie wyeliminuje, że wiele wydziwianie. Dlatego warto zadeklarować drugi klucz sortowania. Jest to jednak mniej efektywne niż na odwrót, ponieważ wyeliminowanie wcześniejszych rzędów byłoby tańsze. Jeśli czasami filtrować przez stamp, ale nie przez type_id, może to mieć sens, aby to zrobić.

+1

Jeśli chodzi o dziwność, typy są zbliżone do grup użytkowników (i raczej drobnoziarnistych), a sygnatury czasowe już przeszły pewne fałdowanie. BTW, uważam, że twój ostatni post na blogu Redshift (http://www.eshioji.co.uk/2013/07/a-simplistic-redshift-trouble-shooting.html) też jest pomocny. – Lorrin

+0

Nie jest to dokładnie czarno-białe, ponieważ typ sortkey ma znaczenie dla wydajności w oparciu o określoną semantykę zapytania, np. przełożony sortkey przewyższyłby kompilator na dużych zestawach danych z bardziej złożonymi zaznaczeniami, jak na http://docs.aws.amazon.com/redshift/latest/dg/t_Sorting_data-compare-sort-styles.html – Arthur

13

Używamy również Redshift i mamy około 2 miliardy rekordów (+20 milionów dziennie) i muszę powiedzieć, że im mniej selektywny jest klucz sort_key, tym bardziej powinien znajdować się na liście sort_key.

W naszym przypadku (i prosimy o zbadanie, w jaki sposób używasz/zapytaj o własne dane) użyliśmy znacznika czasu jako pierwszego parametru sort_key. Problem polega na tym, że nawet w ciągu 1 sekundy rejestrujemy około 200 wierszy, co powoduje, że nasze bloki 1 MB zawierają tylko kilka sekund i każdy typ danych w tym pojedynczym bloku. Znaczenie, mimo że znacznik czasu jest wysoce selektywny, po tym, jak nie możemy naprawdę filtrować dalej, ponieważ mamy wszystkie rodzaje danych w każdym bloku.

Niedawno zmieniliśmy kolejność sort_keys. Pierwszy ma około 15 różnych wartości, drugi ma około 30 itd. ... a znacznik czasu jest ostatnim, ale nadal jeden blok jest nadal mierzony w sekundach.

To powoduje, że (ponieważ używamy pierwszych dwóch kluczy sortowanych jako filtrów bardzo często): stare rozwiązanie: rok danych, wybierz miesiąc, spada 91% bloków, ale po tym, jak ma się otworzyć wszystkie, chociaż chcemy dalej filtrować.

Nowe rozwiązanie obniża około 14/15 bloków w pierwszym kroku, niezależnie od zakresu dat, a następnie około 95% pozostałych, a znacznik czasu nadal spada o 91% pozostałych.

Przetestowaliśmy to dokładnie dzięki dwóm 800 milionom tabel rekordów, które były takie same, z wyjątkiem kolejności sortowania kluczy. Im wyższy okres czasu w klauzuli "gdzie", tym lepsze wyniki uzyskaliśmy. Stało się jeszcze bardziej znaczące w przypadku złączeń oczywiście.

Moja sugestia to, poznaj swoją bazę danych i typy zapytań, które często uruchamiasz, ponieważ najbardziej selektywna kolumna może nie być najlepszym pierwszym parametrem sort_key. Tak jak powiedział Enno Shioji, wszystko zależy od tego, co filtrujesz.

+4

Hmm, interesujące. Odkryliśmy, że jeśli dane docierają z czasem, trzeba je sortować i dzielić przede wszystkim według czasu. W przeciwnym razie działanie VACUUM i operacje szybko stają się zbyt kosztowne (ponieważ ostatnio dostarczone dane muszą być nie tylko posortowane w nowych blokach, ale również powodują zmianę wszystkich starych bloków). – Lorrin

+0

Który klucz DIST najbardziej Ci odpowiada w twoim przypadku? – plinyar

1

powiem postanowienie sort_key powinny być

  1. rozważyć te w dist, filtrem i dołącz pierwszy
  2. rozważyć te w filtrze, dołącz
  3. rozważyć te w filtrze
  4. rozważyć te w dołącz
  5. rozważ te w grupie przez, kolejność (włączając funkcję okna)

ogólna zasada: niższa liczność umieścić pierwszy, jeśli ten sam poziom.