Czy unikatowość pola powoduje, że jest on indeksowany?

10

Jeśli uniqueograniczę pole, czy muszę utworzyć indeks tego pola, aby uzyskać skalowalny czas wstawiania? Czy jest to zrobione dla mnie (nawet jeśli indeks, którego używa, nie jest publicznie dostępny?)

W szczególności pracuję z Apache Derby w zakresie prototypowania, chociaż prawdopodobnie przeniosę go do MySQL w najbliższej przyszłości. Mam również nadzieję, że może być coś w standardzie SQL, co mówi coś o tym.

Nigdy nie będę musiał wyszukiwać według tego pola, więc wolałbym nie tworzyć bezużytecznego indeksu. Ale wolę mieć bezużyteczny indeks niż O(n)czas wstawiania.

corsiKa
źródło
2
Z tego co wiem unikalne ograniczenie jest implementowane za pomocą unikalnego indeksu. W tym pytaniu możesz zobaczyć opinie na temat tej sytuacji: kiedy stosować unikalne ograniczenie zamiast unikalnego indeksu?
Marian
@Marian dzięki za ten link. To było bardzo wnikliwe.
corsiKa

Odpowiedzi:

2

--EDYTOWAĆ--

Moja pierwotna odpowiedź (poniżej) prawdopodobnie nie jest dla ciebie użyteczna, ponieważ nie rozwiązuje problemu uniqueograniczeń. Jak powiedzieli inni, ograniczenia te są zwykle wdrażane z domniemanym unikalnym indeksem. W szczególnych przypadkach może nie być to prawdą (np. W disable novalidateprzypadku Oracle).

Pytanie może brzmieć: Czy można wymusić unikalność bez indeksu? Ogólnie rzecz biorąc, odpowiedź brzmi „nie”, choć w niektórych przypadkach indeks klastrowany oznacza, że ​​indeks i tabela są tym samym obiektem.

--END EDIT--

Powiedziałeś: „Wolę mieć bezużyteczny indeks niż mieć czas wstawiania O (n).”, Ale ogólnie rzecz biorąc, bazy danych nie mają czasu wstawiania O (n). Należy rozważyć dwa przypadki:

  1. Normalna tabela z indeksami lub bez:

    Nowe wiersze są zrzucane u góry stosu. RDBMS prawdopodobnie patrzy tylko na 1 blok, więc nie tylko O ​​(1), ale bardzo mały O (1).

    Jeśli tabela ma indeksy, do każdego z nich zostanie dodany wskaźnik do wiersza. Zwykle będzie to operacja O (log (n)).

  2. Tabela z pewnego rodzaju klastrowaniem, np. Tabela zorganizowana indeksu lub klaster dla Oracle lub Indeks klastrowany dla SQL Server i inne:

    Nowe wiersze są wstawiane do określonego bloku, co może powodować podział lub przepełnienie bloku, ale cokolwiek się stanie, nadal jest to O (log (n)) lub lepsze , spowodowane przez b-drzewa lub podobną strukturę używaną do znalezienia bloku.

Jack mówi, że spróbuj topanswers.xyz
źródło
Ale wyjątkowość bez indeksu byłaby taka, O(n)jak w przypadku całej tabeli. Właśnie tego staram się unikać.
corsiKa
To rzeczywiście najlepsza odpowiedź na to pytanie !!! +1
RolandoMySQLDBA
@Trick - tak, na początku źle zrozumiałem. Obawiam się, że to cena, którą płacisz za ograniczenie wyjątkowości. Czy w twoim przypadku możesz użyć Indeks klastrowany?
Jack mówi, że spróbuj topanswers.xyz
1
@JackPDougless Mogę użyć standardowego „indeksu” i uzyskać O(lg n)czas wstawiania. To nie jest problem. Moje pytanie brzmi: czy system, wiedząc, że potrzebujesz tego indeksu, aby uzyskać przyzwoity czas wstawiania, utworzy dla mnie indeks.
corsiKa
2

KLUCZ PODSTAWOWY> = UNIKALNY> = INDEKS == KLUCZ

Dane InnoDB są zamawiane przez PK. MyISAM PK działa tak samo jak UNIQUE.

INSERT musi dodać „wiersz” do każdego indeksu (dowolnego rodzaju), jaki masz. To zajmuje trochę czasu. (Zwykle za mało czasu, aby mieć znaczenie.) Wszystkie indeksy są przechowywane w formacie BTree. Bloki MyISAM BTree mają rozmiar 1 KB; InnoDB wykorzystuje 16 KB.

Wstawienie do InnoDB powoduje jednocześnie aktualizację PK i danych.

Wstawianie do MyISAM zwykle „dołącza” dane do .MYD. Oddzielnie dodaje wiersz do PK (jeśli istnieje).

INSERT musi najpierw sprawdzić, czy nie ma zduplikowanego klucza dla żadnego klucza PODSTAWOWEGO lub UNIKALNEGO. Odbywa się to za pomocą indeksu. I dlatego dlaczego UNIKALNE i ZAGRANICZNE KLUCZOWE OGRANICZENIA naprawdę budują indeksy. Jest to O (logN), ale zwykle CPU, a nie I / O, ponieważ w przypadku wydajnego buforowania.

Rick James
źródło
Czy masz cytat w specyfikacji InnoDB, który stwierdza, że UNIQUEograniczenie utworzy indeks bez określania przez użytkownika, który ma zostać utworzony?
corsiKa
Hmmm ... Nie, tylko lata doświadczenia.
Rick James
A oto sposób na przetestowanie go ... UTWÓRZ tabelę bez żadnych dodatkowych indeksów; do POKAŻ STATUS TABELI - Długość indeksu będzie wynosić 0. Następnie dodaj UNIKALNY indeks; STATUS TABELI będzie teraz coś pokazywał. (Może być konieczne umieszczenie nietrywialnej ilości danych w tabeli.)
Rick James
1

Aby pogrubić odpowiedź na pytanie: Tak, uczynienie pola unikalnym powoduje indeksowanie go jak klucza podstawowego. W rzeczywistości omówiłem to w innym pytaniu dotyczącym kluczy podstawowych posiadających własną nazwę, aby odróżnić je od innych kluczy unikalnych (kandydujących) .

Jeśli chodzi o ograniczenia, indeksy są tworzone dla Ciebie, dzięki czemu konfigurowany jest paradygmat ograniczeń. Powinieneś być w stanie usunąć zduplikowane indeksy, nawet klucze UNIKALNE, o ile wprowadzone ograniczenie nie odwołuje się do innych kluczy UNIKALNYCH, które osobiście stworzyłeś, oprócz paradygmatu ograniczeń.

Być może nigdy nie będziesz musiał szukać tego pola, ale MySQL na pewno będzie musiał to zrobić, aby określić ważność kluczy i ustalić, jak przejść o wykonywaniu operacji NA USUWANIU KASKADA i NA AKTUALIZACJI KASKADY.

Indeks UNIQUE gwarantuje po prostu wyjątkowość krotek (singletonów, par, trojaczków, ..., n-krotek itp.) W każdym wierszu tabeli.

Według własnego uznania możesz usunąć takie zduplikowane indeksy, pod warunkiem, że nie złamiesz paradygmatu ograniczeń, który posiadasz w tabeli.

RolandoMySQLDBA
źródło
1
To nie odpowiada na moje pytanie. Moje pytanie dotyczy czasu wstawienia. Jeśli masz unikalne ograniczenie, system musi zapewnić unikalność pola przed wstawką - jeśli pole nie ma indeksu, będzie musiał przeszukać całą tabelę ( O(n)). Jeśli istnieje indeks, wyszukiwanie będzie znacznie szybsze (prawdopodobnie O(lg n)). To mój problem. Doskonale zdaję sobie sprawę z mechaniki integralności referencyjnej, martwię się tylko (na potrzeby tego pytania) o wydajność.
corsiKa