Projektowanie pod kątem wykonywania zapytań
Rozwiązania usługi table service mogą być intensywnie korzystające z odczytu, intensywnie korzystające z zapisu lub kombinacji tych rozwiązań. Ten artykuł koncentruje się na kwestiach, które należy wziąć pod uwagę podczas projektowania usługi Table Service w celu wydajnego obsługi operacji odczytu. Zazwyczaj projekt obsługujący operacje odczytu jest również wydajny w przypadku operacji zapisu. Jednak podczas projektowania operacji zapisu omówionych w artykule Projektowanie modyfikacji danych należy wziąć pod uwagę dodatkowe zagadnienia.
Dobrym punktem wyjścia do projektowania rozwiązania usługi Table Service w celu umożliwienia wydajnego odczytywania danych jest pytanie "Jakie zapytania będą musiały zostać wykonane przez moją aplikację, aby pobrać potrzebne dane z usługi Table Service?"
Uwaga
Dzięki usłudze Table Service ważne jest, aby projekt był poprawny z góry, ponieważ jest trudny i kosztowny do późniejszej zmiany. Na przykład w relacyjnej bazie danych często można rozwiązać problemy z wydajnością, dodając indeksy do istniejącej bazy danych: nie jest to opcja z usługą Table Service.
Ta sekcja koncentruje się na kluczowych problemach, które należy rozwiązać podczas projektowania tabel na potrzeby wykonywania zapytań. Tematy omówione w tej sekcji obejmują:
- Sposób wyboru elementu PartitionKey i RowKey wpływa na wydajność zapytań
- Wybieranie odpowiedniego klucza partycji
- Optymalizowanie zapytań dotyczących usługi Table Service
- Sortowanie danych w usłudze Table Service
Sposób wyboru elementu PartitionKey i RowKey wpływa na wydajność zapytań
W poniższych przykładach założono, że usługa tabel przechowuje jednostki pracowników z następującą strukturą (większość przykładów pomija właściwość Sygnatura czasowa w celu uzyskania jasności):
Nazwa kolumny | Typ danych |
---|---|
PartitionKey (nazwa działu) | Ciąg |
RowKey (identyfikator pracownika) | Ciąg |
FirstName (Imię) | Ciąg |
LastName (Nazwisko) | Ciąg |
Age | Liczba całkowita |
EmailAddress (Adres e-mail) | Ciąg |
W artykule Omówienie usługi Azure Table Storage opisano niektóre kluczowe funkcje usługi Azure Table Service, które mają bezpośredni wpływ na projektowanie zapytań. Są to następujące ogólne wskazówki dotyczące projektowania zapytań usługi Table Service. Należy pamiętać, że składnia filtru używana w poniższych przykładach pochodzi z interfejsu API REST usługi Table Service, aby uzyskać więcej informacji, zobacz Jednostki zapytań.
- Zapytanie punktowe jest najbardziej wydajnym wyszukiwaniem do użycia i zaleca się użycie w przypadku odnośników o dużej ilości lub odnośników wymagających najmniejszego opóźnienia. Takie zapytanie może używać indeksów do bardzo wydajnego lokalizowania pojedynczej jednostki, określając zarówno wartości PartitionKey , jak i RowKey . Na przykład: $filter=(PartitionKey eq 'Sales') i (RowKey eq '2')
- Drugim najlepszym rozwiązaniem jest zapytanie zakresu , które używa klucza partycji i filtrów dla zakresu wartości RowKey , aby zwrócić więcej niż jedną jednostkę. Wartość PartitionKey identyfikuje określoną partycję, a wartości RowKey identyfikują podzestaw jednostek w tej partycji. Na przykład: $filter=PartitionKey eq "Sales" i RowKey ge "S" i RowKey lt "T"
- Trzecim najlepszym rozwiązaniem jest skanowanie partycji , które używa klucza partycji i filtrów w innej właściwości innej niż klucz i może zwrócić więcej niż jedną jednostkę. Wartość PartitionKey identyfikuje określoną partycję, a wartości właściwości wybierają podzestaw jednostek w tej partycji. Na przykład: $filter=PartitionKey eq "Sales" i LastName eq "Smith"
- Skanowanie tabeli nie zawiera klucza PartitionKey i jest bardzo nieefektywne, ponieważ wyszukuje wszystkie partycje, które tworzą tabelę z kolei dla wszystkich pasujących jednostek. Spowoduje to przeprowadzenie skanowania tabeli niezależnie od tego, czy filtr używa klawisza RowKey. Na przykład: $filter=LastName eq "Jones"
- Zapytania zwracające wiele jednostek zwracają je posortowane w kolejności PartitionKey i RowKey . Aby uniknąć uciekania się do jednostek w kliencie, wybierz klucz RowKey , który definiuje najbardziej typową kolejność sortowania.
Należy pamiętać, że użycie wartości "lub" do określenia filtru na podstawie wartości RowKey powoduje skanowanie partycji i nie jest traktowane jako zapytanie zakresu. Dlatego należy unikać zapytań używających filtrów, takich jak: $filter=PartitionKey eq "Sales" i (RowKey eq "121" lub RowKey eq "322")
Aby zapoznać się z przykładami kodu po stronie klienta, który używa biblioteki klienta magazynu do wykonywania wydajnych zapytań, zobacz:
- Wykonywanie zapytania punktowego przy użyciu biblioteki klienta usługi Storage
- Pobieranie wielu jednostek przy użyciu LINQ
- Projekcja po stronie serwera
Przykłady kodu po stronie klienta, który może obsługiwać wiele typów jednostek przechowywanych w tej samej tabeli, zobacz:
Wybieranie odpowiedniego klucza partycji
Wybór elementu PartitionKey powinien równoważyć potrzebę włączenia korzystania z transakcji grupy jednostek (w celu zapewnienia spójności) względem wymogu dystrybucji jednostek między wieloma partycjami (w celu zapewnienia skalowalnego rozwiązania).
W jednej skrajności można przechowywać wszystkie jednostki w jednej partycji, ale może to ograniczyć skalowalność rozwiązania i uniemożliwić usłudze tabel możliwość równoważenia obciążenia żądań. W drugiej skrajności można przechowywać jedną jednostkę na partycję, która byłaby wysoce skalowalna i która umożliwia usłudze tabel równoważenie obciążenia żądań, ale które uniemożliwiłyby korzystanie z transakcji grupy jednostek.
Idealnym kluczem partycji jest ten, który umożliwia korzystanie z wydajnych zapytań i ma wystarczające partycje w celu zapewnienia skalowalności rozwiązania. Zazwyczaj okaże się, że jednostki będą miały odpowiednią właściwość, która dystrybuuje jednostki na wystarczające partycje.
Uwaga
Na przykład w systemie, który przechowuje informacje o użytkownikach lub pracownikach, identyfikator UserID może być dobrym kluczem partycji. Może istnieć kilka jednostek, które używają danego identyfikatora UserID jako klucza partycji. Każda jednostka, która przechowuje dane o użytkowniku, jest pogrupowana w jedną partycję, więc te jednostki są dostępne za pośrednictwem transakcji grupy jednostek, a jednocześnie są wysoce skalowalne.
Istnieją dodatkowe zagadnienia dotyczące wybranego klucza partycji , które odnoszą się do sposobu wstawiania, aktualizowania i usuwania jednostek. Aby uzyskać więcej informacji, zobacz Projektowanie tabel pod kątem modyfikacji danych.
Optymalizowanie zapytań dotyczących usługi Table Service
Usługa Table Service automatycznie indeksuje jednostki przy użyciu wartości PartitionKey i RowKey w jednym klastrowanym indeksie, dlatego powodem, dla którego zapytania punktów są najbardziej wydajne do użycia. Nie ma jednak indeksów innych niż w indeksie klastrowanym w kluczu partycji i kluczu wiersza.
Wiele projektów musi spełniać wymagania, aby umożliwić wyszukiwanie jednostek na podstawie wielu kryteriów. Na przykład lokalizowanie jednostek pracowników na podstawie poczty e-mail, identyfikatora pracownika lub nazwiska. Wzorce opisane w temacie Wzorce projektowe tabel dotyczą tych typów wymagań i opisują sposoby pracy z faktem, że usługa Table Service nie zapewnia indeksów pomocniczych:
- Wzorzec indeksu pomocniczego wewnątrz partycji — przechowuj wiele kopii każdej jednostki przy użyciu różnych wartości RowKey (w tej samej partycji), aby umożliwić szybkie i wydajne wyszukiwanie oraz alternatywne zamówienia sortowania przy użyciu różnych wartości RowKey .
- Wzorzec indeksu pomocniczego między partycjami — przechowuj wiele kopii każdej jednostki przy użyciu różnych wartości RowKey w oddzielnych partycjach lub w oddzielnych tabelach, aby umożliwić szybkie i wydajne wyszukiwanie i alternatywne kolejności sortowania przy użyciu różnych wartości RowKey .
- Wzorzec jednostek indeksu — obsługa jednostek indeksu w celu umożliwienia wydajnych wyszukiwań zwracających listy jednostek.
Sortowanie danych w usłudze Table Service
Usługa Table service zwraca jednostki posortowane w kolejności rosnącej na podstawie klucza partycji , a następnie według klawisza RowKey. Te klucze są wartościami ciągów i aby zapewnić prawidłowe sortowanie wartości liczbowych, należy przekonwertować je na stałą długość i wypełnić je zerami. Jeśli na przykład wartość identyfikatora pracownika używana jako RowKey jest wartością całkowitą, należy przekonwertować identyfikator pracownika 123 na 00000123.
Wiele aplikacji ma wymagania dotyczące używania danych posortowanych w różnych zamówieniach: na przykład sortowanie pracowników według nazwy lub data dołączenia. Następujące wzorce dotyczą sposobu alternatywnego sortowania zamówień dla jednostek:
- Wzorzec indeksu pomocniczego wewnątrz partycji — przechowuj wiele kopii każdej jednostki przy użyciu różnych wartości RowKey (w tej samej partycji), aby umożliwić szybkie i wydajne wyszukiwanie oraz alternatywne zamówienia sortowania przy użyciu różnych wartości RowKey.
- Wzorzec indeksu pomocniczego między partycjami — przechowuj wiele kopii każdej jednostki przy użyciu różnych wartości RowKey w oddzielnych partycjach w oddzielnych tabelach, aby umożliwić szybkie i wydajne wyszukiwanie i alternatywne kolejności sortowania przy użyciu różnych wartości RowKey.
- Wzorzec ogona dziennika — pobierz jednostki n ostatnio dodane do partycji przy użyciu wartości RowKey , która sortuje w kolejności odwrotnej daty i godziny.