2011-07-27 10 views
7

Jeśli moja tabela User ma kilka pól, które można wywoływać (np. ID działu, GroupId, RoleId) czy spowoduje jakąkolwiek różnicę szybkości, jeśli utworzę indeks dla każdej kombinacji tych pól?Czy konieczne jest posiadanie indeksu dla każdej kombinacji pól do zapytania w tabeli SQL w celu optymalizacji wydajności?

Przez "możliwy do zapytania", mam na myśli ekran zapytania, w którym użytkownik końcowy może wybrać rekordy na podstawie działu, grupy lub roli, wybierając z listy rozwijanej.

W tej chwili mam indeks na DepartmentId, GroupId i RoleId. To pojedynczy nieunikalny indeks na pole.

Jeśli użytkownik wybierze opcję „nikogo w grupie B”, SQL wygląda następująco:

select * from User where GroupId = 2 

o wskaźniku na GroupID powinna przyspieszyć że w górę.

Ale jeśli użytkownik końcowy wybierz „nikogo w grupie B iw Rola C”, SQL wyglądałby następująco:

select * from User where GroupId = 2 and RoleId = 3 

Posiadanie indeksów GroupID i RoleId indywidualnie mogą nie robi żadnej różnicy, prawda?

Lepszym indeksem dla tego wyszukiwania byłby jeden indeks obejmujący zarówno GroupId, jak i RoleId.

Ale jeśli tak jest, to oznaczałoby, że musiałbym mieć indeks dla każdej kombinacji pól, które można przypisać. Więc muszę wszystkie te indeksy:

  • DepartmentId
  • GroupID
  • RoleId
  • DepartmentId i GroupID
  • DepartmentId i RoleId
  • GroupID i RoleId
  • ID działu, GroupID i RoleId

Czy ktoś może rzucić trochę światła na to? Używam MySQL, jeśli to robi różnicę.

+0

Należy pamiętać, że kolejność kolumn ma znaczenie - (GroupId, RoleId) * nie * jest taka sama jak (RoleId, GroupId). Tak więc na liście brakuje wielu dodatkowych oznaczeń.W przeciwnym razie komentarz @ Joe na temat łączenia indeksów jest dobry (DB2 również to stosuje, aby uzyskać dobry efekt). –

Odpowiedz

7

Wielokolumnowy indeks może być użyty dla każdego lewego prefiksu tego indeksu. W związku z tym indeks na (A, B, C) może być używany do zapytań na (A), (A, B) i (A, B, C), ale nie może na przykład być używany do zapytań na (B) lub (B, C).

Jeśli wszystkie kolumny są indeksowane pojedynczo, MySQL (5.0 lub nowszy) może również używać Index Merge Optimization.

+0

Interesujące. Dopóki więc paramery budowane są w tej samej kolejności za każdym razem, potrzebuję tylko (A, B, C), (A, C), (B, C) i (C) jako cztery całkowite indeksy, które obejmuje wszystkie bazy. – sohtimsso1970

+1

@ sohtimsso1970: Kolejność nie ma nawet znaczenia, ponieważ SQL jest językiem deklaratywnym. To znaczy: "GDZIE A = 1 I B = 2" i "GDZIE B = 2 I A = 1" są takie same i oba mogą używać indeksu na (A, B). –

+0

Dzięki za wyjaśnienia. Z niektórych innych komentatorów wywnioskowałem, że kolejność pól w klauzuli where również miała znaczenie. Jeśli kolejność pól indeksu ma znaczenie, ale klauzula where nie, to praktycznie rzecz biorąc, kolejność pól indeksu również nie ma znaczenia. – sohtimsso1970

1

Stwierdziłem, że najlepiej jest indeksować wszystko, czego użytkownik będzie szukał. Znalazłem lepszą wydajność, tworząc indeksy z wieloma kolumnami, jeśli wyszukiwanie tych kolumn zostanie wykonane.

Na przykład, jeśli ktoś może jednocześnie wyszukiwać zarówno roleid, jak i groupid, posiadanie indeksu z obiema kolumnami będzie faktycznie trochę szybsze niż posiadanie tylko jednego indeksu na każdym z nich. Jednak posiadanie indeksu dla każdej kolumny z zapytaniem może nadal być dobre, ponieważ możesz pominąć kombinację kolumn.

Kluczową sprawą jest sprawdzenie, ile miejsca zajmą indeksy. Ponieważ te kolumny są polami całkowitymi, nie powinna to być wielka sprawa. Trochę czasu na tworzenie indeksów może przynieść znaczne korzyści.

Najlepszą rzeczą do zrobienia będzie eksperymentowanie. Wykonaj wyszukiwanie w wielu kolumnach i ustaw czas, a następnie dodaj indeks łączony i uruchom go ponownie.

2

Moje doświadczenie jest z SQL Server zamiast mysql i możliwe, że to robi różnicę. Jednak ogólnie silnik może korzystać z wielu indeksów w jednym zapytaniu. Chociaż z pewnością istnieją korzyści z posiadania bardziej wszechstronnego pojedynczego indeksu (zapewnia on większy impuls, zwłaszcza jeśli tworzy indeks obejmujący), nadal będziesz czerpać korzyści z używania indeksu w każdym polu zapytania.

Co więcej, należy pamiętać, że każdy indeks musi być utrzymywany osobno, aby zmniejszyć liczbę operacji zapisu w miarę wzrostu liczby indeksów.

0

Usuń wszystkie indeksy i uruchom instrukcje CRUD do tabeli za pomocą bezpłatnego narzędzia o nazwie "Eksplorator planu SQL".

Pokaże ci, które indeksy są potrzebne.

Indeksy są tworzone na podstawie CRUD, a nie na samej tabeli.

+1

Dzięki za podpowiedź, ale oprogramowanie wydaje się działać tylko dla SQL Server. – sohtimsso1970

+0

Istnieje wiele narzędzi, które wykonają dokładnie to samo: http://www.mysql.com/products/enterprise/query.html –

3

Generalnie indeksy będą zwiększyć prędkość kwerendy, ale spadek prędkość wkładka/aktualizacji oraz zwiększyć ilość miejsca na dysku/narzutu. Zatem pytanie, czy powinieneś indeksować każdą kombinację kolumn jest pytaniem, czy powinieneś zoptymalizować każdą funkcję w kodzie. Może sprawić, że pewne rzeczy będą szybsze, lub może ledwie pomóc, i może po prostu zranić więcej, niż pomaga.

Skuteczność indeksów zależy od:

  • Odsetek wybiera vs. wstawkami i aktualizacje
  • specyfiki zapytań SELECT i czy używają oni JOIN
  • Wielkość tabeli są indeksowane
  • RAM i szybkość procesora
  • Ustawienia MySQL określające ile pamięci RAM ma być używane, itp.

Trudno więc podać ogólną odpowiedź. Podstawowa rada dźwiękowa to: Dodaj indeksy, jeśli zapytania są zbyt wolne. Pamiętaj, aby użyć EXPLAIN, aby sprawdzić, które indeksy dodać. Zwróć uwagę, że jest to podobne do ogólnej porady dla bazy danych: profiluj swoją aplikację, zanim poświęcisz czas na optymalizację.

2

Twórz indeksy uważnie! Sugerowałbym zbieranie statystyk zapytań i decydowanie, która kolumna jest częściej używana podczas wyszukiwania, aby można było utworzyć indeks klastrowany w tej konkretnej kolumnie (w każdym razie podczas tworzenia indeksu w wielu kolumnach - fizycznie dane można zamówić tylko w jednej kolumnie)

Należy również pamiętać, że indeks klastrowy może znacznie obniżyć wydajność zapytań o wartości UPDATE/INSERT/DELETE, ponieważ powoduje to zmianę kolejności danych fizycznych.

+0

W tabeli może znajdować się tylko jeden indeks klastrowy. – RocketR

+0

Tak, znam to – sll

+0

Musiałem zrozumieć, że mylisz się co do nowego nowego Clustered index_, sorry. – RocketR

Powiązane problemy