zapytanie w management studio, dużo danych, ale może da się optymalniej?

0

Spójrzcie proszę na kod poniżej, można coś zmienić, żeby było szybciej?

IF OBJECT_ID('[dbo].[b20_dane_ABC_rezer]') IS NOT NULL
 
DROP TABLE b20_dane_ABC_rezer

SELECT
RM_N_INDEX, 
Sum(RM_DEF_TALCE_1) AS RM_DEF_TALCE_1, 
Sum(RM_ETQ_PERP_1) AS RM_ETQ_PERP_1, 
Sum(RM_DEF_TALCE_2) AS RM_DEF_TALCE_2, 
Sum(RM_ETQ_PERP_2) AS RM_ETQ_PERP_2, 
Sum(RM_DEF_TALCE_3) AS RM_DEF_TALCE_3, 
Sum(RM_ETQ_PERP_3) AS RM_ETQ_PERP_3, 
Sum(RM_DEF_TALCE_4) AS RM_DEF_TALCE_4, 
Sum(RM_ETQ_PERP_4) AS RM_ETQ_PERP_4, 
Sum(RM_DEF_TALCE_5) AS RM_DEF_TALCE_5, 
Sum(RM_ETQ_PERP_5) AS RM_ETQ_PERP_5, 
Sum(RM_DEF_TALCE_6) AS RM_DEF_TALCE_6, 
Sum(RM_ETQ_PERP_6) AS RM_ETQ_PERP_6, 
Sum(RM_DEF_TALCE_7) AS RM_DEF_TALCE_7, 
Sum(RM_ETQ_PERP_7) AS RM_ETQ_PERP_7, 
Sum(RM_DEF_TALCE_8) AS RM_DEF_TALCE_8, 
Sum(RM_ETQ_PERP_8) AS RM_ETQ_PERP_8

INTO b20_dane_ABC_rezer

FROM OPENQUERY(REPLIKA_EU, 'SELECT
TABELA03.RESERV_ABC.RM_N_INDEX, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_1, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_1, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_2, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_2, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_3, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_3, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_4, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_4, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_5, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_5, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_6, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_6, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_7, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_7, 
TABELA03.RESERV_ABC.RM_DEF_TALCE_8, 
TABELA03.RESERV_ABC.RM_ETQ_PERP_8

FROM TABELA03.RESERV_ABC')

JOIN [listing].[dbo].[b20_dane_ABC_daty] 
ON RM_N_INDEX = [listing].[dbo].[b20_dane_ABC_daty].EM_N_INDEX

WHERE DATA_START < getdate() AND DATA_END <=getdate()
1

Masz indeksy na datach co ich używasz w where? Ty to odpalasz na dwóch różnych bazach danych? Może połączenie między bazami jest kiepskie. Tu się dużo rzeczy mogło wydarzyć.

0

Tomek Pycia tak, idzie z dwóch baz, wszystkie dane które chcę zapisać do tabeli są pobierane z zewnętrznego serwera, który jest na oraclu, a filtr czyli daty z WHERE są na lokalnej maszynie (sql server express + management studio). Nie mam indeksów ani kluczy podstawowych, ale mogę mieć, jak tylko mi napiszecie jak to ustawić. Klucz podstawowy mogę ustawić tylko jeden na tabelę? Jak z indeksami?

1

Goole wyłączyli? Indeksów zakładasz ile chcesz. Poszukaj jak to zrobić. A sprawdziłeś ile czasu wykonuje sie to podzapytanie z bazy Oracla ? Może być problem sieciowy i nic z tym nie zrobisz na tym poziomie.

2

W tym co wkleiłeś brakuje group by, ale jeżeli cała agregacja jest robiona po stronie SQLServera, to on musi zaciągnąć wszystkie dane. I póżniej je agregować. Czyli pobierasz nadmiar danych, przerzuciłbym to agregowanie na replika_eu wtedy dostaniesz wynik, anie będziesz go przeliczał na SQL Serverze. Nie wiem ile tam jest danych, ale podejrzewam, że sporo "zaoszczędzisz"

0

Panczo GROUP BY RM_N_INDEX; jest na samym końcu, czyli po WHERE, jak powinien ten kod wyglądać, żeby agregacja dokonywała się po stronie servera, sumy
Sum(RM_DEF_TALCE_1) AS RM_DEF_TALCE_1, ....2, ....3, itd przenieść za OPENQUERY czy wystarczy GROUP BY RM_N_INDEX; przez FROM TABELA03.RESERV_ABC. Na serwerze przed agregacją może znajdować się nawet 1.2 miliona linii 22 kolumny, dzisiaj 920 tyś. nie ściągam wszystkich, ale teraz zajmuje to 1h 44 minuty.

Tomek Pycia indeksy znalazłem, dziękuję. Niestety teraz już nic nie sprawdzę, nie mam dostępu do serwera.

1

No właśnie ściągasz, jeżeli agregacja jest po stronie serwera SQL, to najpierw masz pobranie danych z Linked serwera (tu zależnie od rozmiaru, ale w locie tego nie liczy, więc temdb dostaje po dupie) później join z tabelą i agregacja, przerzuć group by do open query to będziesz ciągnął zagregowne dane, a nie wszystkie.

Prosty test ile zwraca rekordów zapytanie na oracle?

SELECT
RM_N_INDEX, 
Sum(RM_DEF_TALCE_1) AS RM_DEF_TALCE_1, 
Sum(RM_ETQ_PERP_1) AS RM_ETQ_PERP_1, 
Sum(RM_DEF_TALCE_2) AS RM_DEF_TALCE_2, 
Sum(RM_ETQ_PERP_2) AS RM_ETQ_PERP_2, 
Sum(RM_DEF_TALCE_3) AS RM_DEF_TALCE_3, 
Sum(RM_ETQ_PERP_3) AS RM_ETQ_PERP_3, 
Sum(RM_DEF_TALCE_4) AS RM_DEF_TALCE_4, 
Sum(RM_ETQ_PERP_4) AS RM_ETQ_PERP_4, 
Sum(RM_DEF_TALCE_5) AS RM_DEF_TALCE_5, 
Sum(RM_ETQ_PERP_5) AS RM_ETQ_PERP_5, 
Sum(RM_DEF_TALCE_6) AS RM_DEF_TALCE_6, 
Sum(RM_ETQ_PERP_6) AS RM_ETQ_PERP_6, 
Sum(RM_DEF_TALCE_7) AS RM_DEF_TALCE_7, 
Sum(RM_ETQ_PERP_7) AS RM_ETQ_PERP_7, 
Sum(RM_DEF_TALCE_8) AS RM_DEF_TALCE_8, 
Sum(RM_ETQ_PERP_8) AS RM_ETQ_PERP_8
from
TABELA03.RESERV_ABC
group by 
RM_N_INDEX

Bo jak to wstawisz do OPENQUERY to sporo roboty odejdzie po stronie SQL Servera, jak i powinna spaść ilość przepychanych danych...

0

krótko zwięźle i na temat,
Nie mogę założyć jednego klucza, dostaję komunikat, jak poniżej, rozumiem, że chodzi o to, że w tej kolumnie mam powtarzającą się wartość, ale sprawdzam i nie widzę, żeby którakolwiek wartość się dublowała.
Msg 1505, Level 16, State 1, Line 54
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.b95_dane_podstawowe' and the index name 'PK__b95_dane__21C79B603A35AE99'. The duplicate key value is (01598443).
Msg 1750, Level 16, State 0, Line 54
Could not create constraint or index. See previous errors.
The statement has been terminated.

w pozostałych tabelach/kolumnach po których będę łączył lub filtrował pozakładane klucze i indeksy

ALTER TABLE b95_dane_podstawowe
ADD PRIMARY KEY (abc_indeks)
CREATE INDEX indx_data_sub ON [listing].[dbo].[b95_dane_podstawowe](data_konca, data_poczatku)

obliczenia, które się dało, przeniesione na serwer oracla....... i

SZALEŃSTWO, przetwarzanie z 1h: 44 minuty skrócone na 2 minuty 55 sekund.

Panczo, Tomek Pycia wielkie dzięki

1

Komunikat błędu wynika z tego, że zakladasz unkalny index, czyli taki króry się nie powtarza. Ty musisz założyć index nieunikalny: https://docs.oracle.com/cd/B28359_01/server.111/b28310/indexes003.htm#ADMIN11723

0

Panczo jak usunąć duplikaty z tabeli

b95_dane_podstawowe

kolumna
abc_indeks

0

A poco chcesz je usuwać? To nie jest wskazane jak kolumna nie powinna być unikalana

select value, count(*)  from tabela group by value haveing count(*)> 1 

To ci pozwoli znaleźć duplikaty. Sam musisz ocenić czy są to prawidłowe dane czy nie.

0

duplikaty już mam i wiem, że jest "gap error" w tabeli źródłowej, stąd zdublowane wartości.

1

Ale chcesz je usunąć z bazy, zmienić na inną wartość czy co z nimi chcesz zrobić ?

0

chcę usunąć z mojej bazy. Na oracla nie mam wpływu, "do odczytu tylko".

0

sytuacja opanowania za pomocą CTE (którego wcześniej, nie wiedzieć czemu nie ogarniałem) i finalnie tabela czyściutka, indeksy i klucz podstawowy założony.

;WITH cte AS (SELECT abc_indeksy, ROW_NUMBER() OVER (PARTITION BY abc_indeksy ORDER BY abc_indeksy) row_num FROM b95_dane_podstawowe) DELETE FROM cte WHERE row_num > 1

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