Tworzę aplikację w Ruby on Rails z bazą danych PostgreSQL (9.4). W moim przypadku użycia kolumny w tabelach będą bardzo często wyszukiwane, ponieważ cały punkt aplikacji szuka bardzo specyficznych atrybutów w modelu.
Obecnie jestem podejmowaniu decyzji, czy użyć integer
typu lub po prostu użyć typowy typu string (np character varying(255)
, który jest domyślny w Rails ) do kolumn, jak nie jestem pewien, co różnica wydajności będzie na indeksie.
Te kolumny są wyliczeniami . Mają stały rozmiar dla liczby możliwych wartości, jakie mogą mieć. Większość długości wyliczeń nie przekracza 5, co oznacza, że indeks byłby mniej więcej ustalony przez cały okres użytkowania aplikacji ; dlatego indeksy liczb całkowitych i łańcuchów byłyby identyczne pod względem liczby węzłów.
Jednak ciąg, który byłby indeksowany, może mieć długość około 20 znaków, co w pamięci jest około 5 razy dłuższe niż liczba całkowita (jeśli liczba całkowita wynosi 4 bajty, a ciągi są czystymi ASCII o 1 bajcie na znak, to jest to zachowane). Nie wiem, w jaki sposób silniki baz danych wykonują wyszukiwania indeksów, ale jeśli trzeba „zeskanować” ciąg znaków, dopóki nie będzie dokładnie pasował , to w gruncie rzeczy oznacza to, że wyszukiwanie ciągu będzie 5 razy wolniejsze niż wyszukiwanie liczb całkowitych; „skanowanie” do momentu dopasowania liczby całkowitej będzie wynosić 4 bajty zamiast 20. Oto, co sobie wyobrażam:
Wartość wyszukiwania to (liczba całkowita) 4:
skanowanie ............................ ZNALEZIONO | uzyskiwanie rekordów ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Wartość wyszukiwania to (ciąg) „some_val” (8 bajtów):
łów................................................. .................................... ZNALEZIONO | uzyskiwanie rekordów ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Mam nadzieję, że to ma sens. Zasadniczo, ponieważ liczba całkowita zajmuje mniej miejsca, można ją „dopasować” szybciej niż jej ciąg znaków. Być może jest to całkowicie błędne przypuszczenie, ale nie jestem ekspertem, dlatego właśnie was pytam! Przypuszczam, że ta odpowiedź, którą właśnie znalazłem, wydaje się potwierdzać moją hipotezę, ale chcę mieć pewność.
Liczba możliwych wartości w kolumnie nie zmieniłaby się przy użyciu żadnej z nich, więc sam indeks nie zmieniłby się (chyba że dodałem nową wartość do wyliczenia). Czy w takim przypadku wystąpiłaby różnica w wydajności przy użyciu integer
lub varchar(255)
, czy też użycie typu liczby całkowitej ma większy sens?
Pytam dlatego, że enum
typ Railsów odwzorowuje liczby całkowite na klucze łańcuchowe, ale nie mają one być kolumnami skierowanymi do użytkownika. Zasadniczo nie można zweryfikować, czy wartość wyliczenia jest poprawna, ponieważ niepoprawna wartość spowoduje, że ArgumentError
przed uruchomieniem jakichkolwiek sprawdzeń poprawności. Użycie string
typu pozwoliłoby na sprawdzanie poprawności, ale jeśli istnieje koszt wydajności, wolałbym po prostu rozwikłać problem sprawdzania poprawności.
źródło
varchar(255)
npvarchar(260)
. Mogło być coś takiego z SQL Server 6.x, ale nie było to prawdą przez długi czas.