Różnice między polami VARCHAR a INTEGER w kluczach
Używam całkowitoliczbowych identyfikatorów jako kluczy głównych w moich tabelach. Co jeśli zamiast tego użyłbym pól varchar? Czy stracę na wydajności w takim przypadku, zwłaszcza przy dużych tabelach? Czy złączenia będą działać tak szybko, jak w przypadku kolumny całkowitoliczbowej?
Twoja wydajność powinna być mniej więcej taka sama w przypadku varcharów i liczb całkowitych. Firebird zawsze porównuje klucze indeksów bajt po bajcie i przechowywana jest tylko znacząca część wartości.
Pojedyncze pole klucza jest najpierw konwertowane do jednego z trzech typów kanonicznych: łańcucha z sortowaniem, podwójnej precyzji oraz (niestety) 64-bitowej liczby całkowitej. Daty stają się liczbami zmiennoprzecinkowymi podwójnej precyzji.
Łańcuchy, które mają sortowanie inne niż ich wartość bajtowa, są konwertowane do formatu sortowania. To trochę czarna magia i zwiększa rozmiar łańcucha, ale efekt jest taki, że łańcuch znajduje swoje właściwe miejsce podczas sortowania z innymi łańcuchami o tym samym sortowaniu. ‘A’, ‘a’, ‘â’, ‘á’, ‘Ă’, ‘ã’, ‘ä’, ‘å’, ‘ă’, ‘ą’, ‘Ā’ - wszystkie pojawiają się na swoich wyznaczonych miejscach. (Przepraszam za to, co to zrobiło z Twoim klientem pocztowym… w moim to jedenaście wariantów litery ‘A’.) Końcowe spacje nie są uwzględniane w kluczu.
Liczba podwójnej precyzji jest modyfikowana, aby również sortowała się bajt po bajcie - z grubsza odwrócenie znaku, potem wykładnika, potem mantysy, z obcięciem końcowych zer.
W zależności od endianowości 64-bitowych liczb całkowitych na komputerze, one również są modyfikowane, aby porównywać się bajt po bajcie. To może wydawać się nieoptymalizacją, ale klucze indeksów nie są przechowywane na naturalnych granicach i podlegają kompresji prefiksowej, więc nie ma możliwości użycia większego porównania niż bajt po bajcie.
Klucze złożone są bardzo podobne. Każda część jest konwertowana do swojego typu klucza indeksu i dopełniana do wielokrotności 4 bajtów. Po każdych czterech bajtach Firebird dodaje bajt z pozycją bieżącego pola klucza. Tak więc indeks na LastName, FirstName, ZodiacSign wyglądałby jak 1Harr1ison2Ann 3Gemi3ni. Pozwala to uniknąć zawstydzającego pomylenia Damnation z Dam nation.
Dlaczego powiedziałem „(niestety)" powyżej? Ponieważ posiadanie jednego formatu dla liczb pozwala Firebirdowi zmieniać rozmiar liczb bez odtwarzania na nich indeksów. Ale kiedy Borland dodał z powrotem 64-bitowe liczby całkowite - InterBase miał 64-bitowe liczby całkowite od początku na maszynach VAX - jakiś bystry umysł zauważył, że podwójna precyzja ma 56 bitów precyzji, a 64-bitowe liczby całkowite mają 64 bity. Z drugiej strony indeksy Firebirda są zaprojektowane tak, aby radzić sobie z pewną niedokładnością… albo pozostałe 8 bitów można dodać na końcu… cokolwiek. Więc musisz przebudować indeksy przy przejściu z Numeric/Decimal 9 na Numeric/Decimal 12. Smutne.
„Kompresja prefiksowa?" Podczas przechowywania klucza innego niż pierwszy na stronie lub pierwszego po skoku na stronie, Firebird patrzy na poprzedni klucz i obcina tę część początku następnego klucza, która powiela poprzednika, i dodaje długość obciętej części na początku. Tak więc łańcuchy „AAAA", „AAAB", „AAAC", „AABC" stają się
„AAAA", „3B", „3C" i „2BC". Istnieje problem z niektórymi formatami GUID, które umieszczają zmienną część liczby na początku, a stałą część na końcu. To niweczy kompresję prefiksową i zwiększa rozmiar indeksów.
„Skok?" - Kompresja prefiksowa znacznie zmniejsza rozmiar indeksów, redukując operacje wejścia/wyjścia, ale wymaga odczytu całej strony w celu odszyfrowania klucza. W porządku przy stronach 1K, ale przy większych rozmiarach stron obliczenia były nie do przyjęcia. Dlatego każda strona indeksu ma teraz własny indeks wskazujący na offsety nieskompresowanych wpisów. Taki indeks nazywany jest wektorem skoków.
Ann Harrision