Wpis z mikrobloga

Mirasy i Węgierki z tagu #sql

W pracy czasami muszę się podłączyć do zewnętrznego serwera DB2 i w tym celu używam OPENROWSET. Chciałbym jednak wtedy wybierać tylko wiersze, które odpowiadają kluczowi na naszym własnym serwerze, często jest ich kilkadziesiąt tysięcy. O ile potrafię to połączyć i pobrać tylko to co mnie interesuje, tak często trwa to bardzo długo i zapewne obciąża serwer zewnętrzny, a wolałbym jak najmniej go nadwyrężać. Jaki rodzaj JOINa najlepiej się do tego nadaje? Bądź może inna metoda? Pobierania całej tabeli, która ma miliony wierszy na serwerze zewnętrznym, a następnie robienia lokalnie joina wolałbym uniknąć ( ͡° ͜ʖ ͡°)

A, korzystamy z MS SQL Server jako naszego serwera.

#naukaprogramowania
  • 13
@DarkAlchemy:

potrafię to połączyć i pobrać tylko to co mnie interesuje


W jaki sposób? Jeśli robisz joina tabeli na zewnętrznym serwerze z kilkoma lokalnymi, to może tu leży problem - ms sql słabo radzi sobie z szacowaniem kosztu takich zapytań i zwykle przyjmuje nieoptymalny plan zania (co wcale nie oznacza, że serwer zwwnętrzny jest bardzo obciążany).

Czytając dane z zewnętrznego serwera czytasz tylko potrzebne dane? Są tam indeksy? Korzystasz z nich?
@DarkAlchemy: Just don't :) To jest bardziej temat dla SSIS / pracy na serwerze źródłowym niż zapytań - głównie z uwagi na wspomniane nadwyrężanie. Z drugiej strony kilkadziesiąt tysięcy to nie jest coś, z czym jakikolwiek sensowny serwer powinien mieć problemy ;)
@Dionizja: chcę czytać tylko potrzebne dane, ale problem przedstawię na przykładzie:
Mam listę ID klientów, co do których dane chcę wyciągnąć, na naszym serwerze (klucz jednej z tabel tymczasowych). Jeśli chciałbym wyciągnąć tę samą listę klientów na serwerze zewnętrznym to bym musiał kilka joinów na dosyć dużych tabelach tam wykonać. Więc mam to i teraz z serwera DB2 (jedna tabela, ale z milionami wierszy) chcę wyciągnąć wszystkie zamówienia stworzone przez tych
mogę, ale to wiąże się z dodatkową ilością joinów do innych dużych tabel i chyba jednak to co robię jest sprawniejsze (a może się mylę?)


@DarkAlchemy: Robisz sobie proste polecenie które skleja zapytanie i wsadza wszystkie id klientów do SELECT * from foreignserver.table WHERE user_id IN (...), powinny ci przylecieć tylko wybrane wiersze. Powinno być szybciej ale musisz przetestować, szansa że trafisz na limit wielkości zapytania jest mała ale możliwa.
@plushy: robię tak jak mam kilka-set ID (jedno ID to 15 znaków z zerami wiodącymi), że po prostu je wrzucam w WHERE, ale jak jest ich kilkanaście tysięcy to pewnie trafię na limit długości Stringa (OPENROWSET operuje na stringach biblioteki, konfiguracji połączenia i samego query, chyba że to też można jakoś obejść)
@DarkAlchemy: ;) Dlaczego więc nie paczka SSIS? Zakładam, że serwer po drugiej stronie jest spory i poradzi sobie z kilkoma równoległymi zapytaniami. Możesz wtedy sterować wielkością where'a w każdym zapytaniu i wyciągnąć więcej niż z pojedynczego wywołania.

No i oczywiscie - jeżeli masz trochę większy dostęp do zdalnego serwera niż read-only, możesz też zrobić tabelę tymczasową z IDsami po ich stronie i dropnąć ją na koniec zapytania (lub odwrotnie - wywołać
@NdeV: SSIS pobiera mnóstwo danych w nocy ( ͡° ͜ʖ ͡°)
Czasami po prostu potrzeba czegoś na już, czego nie trzymamy u siebie bo nie ma po co zużywać miejsca, albo nikt nie przypuszczał, że będzie potrzebne, i wtedy są takie problemy. A dostęp tylko Read-Only, w życiu bym nie chciał odpowiadać jakby cokolwiek się zepsuło na tym serwerze xD (a przynajmniej nie za takie pieniądze (