Witam.
Próbuję skrócić jakoś dostęp do bazy danych dla jednego zapytania, które strasznie piłuje serwer. Jego wykonanie to około 3 - 4 minuty. Ilość rekordów w tabeli to ponad 100 000, serwer stary i pewnie dlatego tak długo trwa. Myślałem, aby użyć widoku, ale to nie da do końca takiego zamierzonego efektu.
Myślałem, aby napisać procedurę, która będzie się uruchamiać o wyznaczonej godzinie i aktualizować utworzoną przeze mnie tabelę z danymi. Dane w tabeli będą miały postać już zsumowanych wartości w zależności od indeksu. Potem, jak będę chciał pobrać te dane, to po prostu wpiszę:
Select * From Moja_Tabela
Where Year = @myYear
Myślę, że tabele będzie przedstawiona jakoś tak:
Create Table Tabela (
IdIndex Char (30),
Opis Char(30),
Typ char(30),
Ilość integer,
Wartosc Money,
Miesiac integer,
Rok integer
)
Nie wiem, jak wygląda sprawa z kluczami głównymi. Wiem, że dobrą praktyką jest sprowadzenie tabeli przynajmniej do 3 postaci normalnej, ale jedyne co mi przychodzi na myśl, to utworzenie numeru wiersza i jego autoinkrementacja. Choć, tak sobie myślę, nie powinno być problemu z powtarzającymi się danymi, ale tego tak nie sprawdzałem.
Zastanawiam się nad tym, w jaki sposób aktualizować tą tabelę. Chodzi o to, że codziennie będę wprowadzał do niej dane, ale w taki sposób, aby były pogrupowane w rok i miesiąc.
Czyli, jeżeli w tabeli mam już rekord:
IdIndex | [size=2]Opis | Typ | Ilość | Wartosc | Miesiac | Rok[/size]
Głośnik | Niskotonowy | Muzyka | 20 | 233.45 | 3 | 2014
I chcę tabelę zaktualizować danymi:
IdIndex | [size=2]Opis | Typ | Ilość | Wartosc | Miesiac | Rok[/size]
Głośnik | Niskotonowy | Muzyka | 15 | 170.09 | 3 | 2014
To mogę spokojnie użyć Update.
Create table TMP ...
Insert Into TMP ....
Update Tabela
Set Tabela.Ilosc= TMP.Ilosc, Tabela.Wartosc = Tmp.Wartosc
From Tabela
INNER JOIN TMP
On Tabela.IndexId = TMP.IndexID AND Tabela.Miesiac = TMP.Miesiac ....
WHERE
Tabela.Ilosc!= TMP.Ilosc or
Tabela.Wartosc != TMP.Wartosc or
(TMP.Ilosc is not null and Tabela.Ilosc is null) or
(TMP.Wartosc is not null and Tabela.Wartosc is null)
Ten przykład wziąłem ze strony: StackOverflow i jeszcze nie sprawdziłem jego działania.
Ale jeżeli się okaże, że np. jest to nowy miesiąc, lub wprowadzony nowy indeks, który jeszcze w tej tabeli nie wystąpił, to wtedy będę musiał użyć polecenia INSERT INTO, bo UPDATE nie zadziała, wnioskuję ze sposobu działania tej funkcji.
I jak tu stwierdzić, czy użyć INSERT czy UPDATE. Na chwilę obecną, jedynie co mi przychodzi na myśl to usunięcie danych z konkretnego miesiąca i wstawienie nowych z tabeli TMP. Wtedy zawsze będę używał INSERT, nie wiem, czy jest jakaś lepsza i mądrzejsza metoda.
W przypadku, gdy serwer padnie a miesiąc się cały usunie, wtedy trzeba będzie czekać aż się zadanie uruchomi i uaktualni "Tabela", albo samemu aktywować zadanie.