Refleksja nt optymalizacji [MYSQL]

0

Witam. Dla celów posłuży nam tabela kalendarza, taki bardziej rozbudowany np jakiś firmowy.

Rok {K} | DzienID {K} | TydzienID | Data
2010 1 1 2010-01-01
2010 2 2 2010-01-09
2010 3 2 2010-01-10
2010 4 2 2010-01-11
2010 5 3 2010-01-10
2010 6 3 2010-01-15
2010 7 4 2010-01-20
2011 1 1 2011-01-01
2011 1 1 2011-01-01
2012 1 1 2012-01-01
2013 1 1 2013-01-01

Kluczem jest tutaj Rok i ID dnia.
Przykładowo chce wyswietlić dane za 1 tydzień roku 2010.
Co powinno być najpierw ?

1. SELECT ... WHERE Rok=2010 AND TID=1
2. SELECT ... WHERE TID=1 AND Rok=2010

W pierwszym wypadku WYDAJE mi się, że wyselektuje do jakiegoś tempa 7rekordów, a potem z niego 1 rekod.
W drugim wypadku wyselektuje 5 rekordow w pierwszej czesci warunku a potem z niego 1.

Tylko ze tu jest haczyk: struktura jest typu BTREE, nie wiem dokladnie jak to jest zrobione, ale na pewno wezly jakos sa pogrupowane wg kluczy głównych. Wiec prawdopodbnie pierwszy sposob selekta bedzie lepszy.... ?!
Generalnie jak pisalem zapytania to stosowalem sie zasady, ze na poczatku warunki kluczowe, od tych 'najgrubszych' a na koncu warunki niekluczowe. Czy tak bedzie zawsze najoptymalniej ?

  1. Oraz takie poboczne pytanie: czy majac Rok i DzienID, da sie wyselektowac wszystkie dane z tygodnia w ktorym jest DzienID ? (Nie uzywajac funkcji dat, tylko na podstawie pola 'TydzienID'). Pewnie pozostaje podzapytanie ? (Selekt w selekcie).
0
  1. Ta tabela to jest porażka, bo masz tam jawną redundancję danych. Przecież year(Data) zwróci ci rok!
  2. To zależy od tego jakie masz pozakładane indeksy. Powinieneś szukać po polu na którym masz indeksy, bo tak będzie najszybciej. Poza tym pierwsze powinny być warunki które ograniczą wyniki jak najbardziej (żeby 2,3,4 warunek w WHERE sprawdzać już dla małej ilości potencjalnych rekordów)
  3. Tego drugiego pytania w ogóle nie rozumiem. Napisz je jeszcze raz, tym razem po polsku. Albo pokaż co byś chciał z tej bazy wyciągnąć...
0
  1. To nie jest żadna porażka... tabela jest jak najbardziej jako tabelka pomocnicza.
0

Zawsze chętnie dowiem sie czegoś nowego, więc mam pytanie: jaka jest korzyść z trzymania w tabeli osobno roku, skoro mamy całą datę z której ten rok można wyciągnąć za pomocą year()?

0

Prawie wszystkie bazy mają optymalizator zapytań, więc generalnie nie powinno mieć znaczenia jaka jest kolejność warunków, o ile zapytania są równoważne. Dla prostych zapytań jednak baza może czasem uznać, że optymalizacja zapytania wydłuży całkowity czas i jej nie przeprowadzi. Pasowałoby zajrzeć do dokumentacji.

0

O ja.... Pisałem ze to nie jest ZWYKŁY kalendarz... jeszcze zaznaczyłem ze to jest FIRMOWY, ale jak zwykle sie ktos musial dop*** nie do tego co trzeba :P Nie wiem czy jesteś w stanie sobie wyobrazić że w roku 2010, mogą byc daty z 2011 i 2009 ? (np jakas produkcja, jest oznaczona 2010, ale moze sie przeciagnac pare dni na nowy rok).
To była pierwsza zaleta takiego pola, a druga jest taka ze YearOf to jakas funkcja, samo nie wyczaruje roku. Ciekawe ile ci na kartce zajmie Ci przeksztalcenie double na rok :P
Trzecia zaleta wynika z tego ze moga byc dwie rownolegle produkcje: i wtedy obok Roku jest takze jakis ID, i daty moga sie wtedy nakladac.

Co do zapytan to pisalem, niby na poczatku sie powinno stosowac te co najbardziej ograniaczaja wyniki, tyle ze jest chyba roznica pomiedzy warunkach na polach kluczowych i niekluczowych ? (pomijajac indeksy, zakladamy ze sa domyslne czyli na kluczach glownych). Chyba ze mam rozumiec, ze dodanie indeksu na pole, jest rownoznaczne z identyczna wydajnoscia jak by byl sam kluczem..

  1. A co do drugiego mojego pytania(było napisane po Polsku, ale coz, moze troche zagmatwane :P). Mając Rok np 2010 i DzienID np 1, to numer tygodnia w tej tabeli jest rowny '1'. I teraz chce wyselektowac wszystkie dane ktore maja wlasnie ten TydzienID='1'. I czy jedyna mozliwoscia to
SELECT * FROM cal WHERE Rok=2010 AND TydzienID IN(Select TydzienID FROM cal WHERE DzienID=1 AND Rok=2010)
0
Shalom napisał(a)

Zawsze chętnie dowiem sie czegoś nowego, więc mam pytanie: jaka jest korzyść z trzymania w tabeli osobno roku, skoro mamy całą datę z której ten rok można wyciągnąć za pomocą year()?

Proszę bardzo: http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1