Obecnie mamy istniejącą bazę danych i aplikację, która jest w pełni funkcjonalna. W tym momencie nie mam możliwości zmiany architektury. Dzisiaj każda tabela w bazie danych ma pole „IsDeleted” NOT NULL BIT z domyślną wartością „0”. Gdy aplikacja „usuwa” dane, po prostu aktualizuje flagę IsDeleted na 1.
Trudno mi zrozumieć, w jaki sposób należy ustrukturyzować indeksy w każdej tabeli. W tej chwili każde zapytanie / dołącz / etc zawsze implementuje kontrolę IsDeleted. Jest to standard, którego muszą przestrzegać nasi programiści. Biorąc to pod uwagę, próbuję ustalić, czy wszystkie moje klastrowane indeksy klucza podstawowego w każdej tabeli muszą zostać zmienione, aby uwzględnić klucz podstawowy ORAZ pole BIT IsDeleted. Również od KAŻDEGO zapytania / dołączenia / etc. musi zaimplementować kontrolę IsDeleted, czy właściwe jest założenie, że KAŻDY POJEDYNCZY indeks (również niesklastrowany) powinien zawierać pole IsDeleted jako pierwsze pole indeksu?
Mam jeszcze jedno pytanie dotyczące przefiltrowanych indeksów. Rozumiem, że mogłem umieścić filtry w indeksach, takie jak „WHERE IsDeleted = 0”, aby zmniejszyć rozmiar indeksów. Ponieważ jednak każde sprzężenie / zapytanie będzie musiało zaimplementować kontrolę IsDeleted, czy uniemożliwiłoby to użycie filtrowanego indeksu (ponieważ kolumna IsDeleted jest używana w sprzężeniu / zapytaniu)?
Pamiętaj, że nie mam możliwości zmiany podejścia IsDeleted.
źródło
IsDeleted
kolumny, niezależnie od fizycznego przechowywania, prawdopodobnie sensowne byłoby ujawnienie danych przez dwa widoki (opcjonalnie w różnych schematach), rozwiązując zarówno problem parametryzacji, jak i popełniając błędy przy dostępie do danych, które nie powinny były być dostęp jest mniej prawdopodobny. Dostęp do danych podstawowych ma znaczenie tylko w rzadkich przypadkach, w których usunięte i nieskasowane dane muszą być w jakiś sposób połączone, a wiersze faktycznie muszą zostać przełączone na „usunięte”.To może być niepopularna opinia, ale nie sądzę, że istnieje „rób to wszędzie” / jeden rozmiar pasuje do wszystkich odpowiedzi na twoje pytanie.
Jeśli masz zapytania, które skanują wiele wierszy IsDeleted bez powodu, jednym z rozwiązań jest utworzenie filtrowanego, nieklastrowanego indeksu w celu spełnienia tego zapytania.
Inną opcją jest utworzenie widoku indeksowanego, który może być wykorzystany przez wiele różnych zapytań, które są filtrowane tylko do nieusuniętych wierszy. Może to być szczególnie przydatne w wersji Enterprise Edition, gdzie automatyczne indeksowane dopasowywanie widoków działa bez podawania
NOEXPAND
podpowiedzi.W przypadku małych tabel lub tabel, które są mocno odczytywane, dodawanie filtrowanych nieklastrowanych indeksów lub widoków lub cokolwiek innego może być po prostu dodawaniem niepotrzebnego narzutu do bazy danych.
źródło
Przy rozsądnym założeniu, że usuwanie jest rzadkie, brak zmian w indeksach jest właściwym rozwiązaniem.
Odkryłem, że prędzej czy później trzeba zapytać o odniesienia do usuniętych wierszy, a wiersze znajdujące się w indeksach są nagle bardzo tego warte.
Pamiętaj, że o ile nie korzystasz z widoków, musisz edytować wszystkie zapytania, aby i tak uwzględnić filtry.
źródło
Widziałem system, w którym flaga IS_DELETED ma wartość 0 lub wartość PK. W innych systemach był to minus PK.
Ponieważ większość zapytań pobierała wartości za pomocą klucza „naturalnego” lub biznesowego (czasem wielozadaniowego), nigdy nie były one pytane przez PK z wyjątkiem połączeń ale zawsze dodawali AND IS_DELETED = 0 na końcu dla głównej tabeli i wszystkich połączonych tabel.
Ten system miał również tabelę kontroli dla każdej tabeli transakcyjnej, która śledziła zmiany; a aplikacja miała funkcję wyświetlania wszystkich zmian danych, w tym usuniętych danych.
źródło
Mam nadzieję, że masz prawo i możliwość zmiany zapytania.
Chciałem powiedzieć jedną ważną kwestię, mam nadzieję, że uda mi się to wyjaśnić.
W złożonym zapytaniu, gdzie
Transaction table
iMaster
tabele są używane.Używaj
IsDeleted=0
tylko wTransaction
tabeli. Nie używać wMaster
tabeli.Przykład,
Nie ma sensu
c.isdeleted=0
(używanie wCategory
tabeli). Nie jest to konieczne.Podobnie, czy warto używać
P.isdeleted=0
?Ponieważ chcę całego nieskasowanego Porządku i ich szczegółów.
Jak można
Product
usunąć, kiedyOrder
jestActive
lub gdziekolwiekProductid
jest odwołanie.W ten sposób, jeśli ostrożnie debugujesz w ważnym zapytaniu, być może możesz usunąć część isdeleted = 0.
Nie twórz na ślepo indeksu filtrowanego, najpierw wybierz wszystkie bardzo ważne i powolne zapytania.
Zoptymalizuj te powolne zapytania, a następnie zdecyduj tylko o Filtrowanym indeksie lub dostosuj indeks.
źródło