Optymalizacja połączenia do bazy

0

Witam,
od niedawna zacząłem programować w C# i spotkałem się z pewnym problemem, w trakcie zaciągania danych z bazy wyrzuca mi wyjątek: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Niestety nie mogę zmienić zapytania które jest wysyłane do SQL więc trzeba coś zoptymalizować w kodzie C# niestety nie mam pojęcia co. Kiedy podaję mały zakres dat które ma uwzględniać np. 2dni jest ok gdy daje więcej to jest problem. Poszukuję więc jakiegoś znawcę który pomoże, proszę więc o pomoc.
Poniżej kod C#

private void to_csv_Click(object sender, EventArgs e)
{

polaczenie = new SqlConnection();

polaczenie.ConnectionString = "Data Source=KRIS\\SQLEXPRESS;" + "Trusted_Connection=yes;" + "database=DUOTES; " + "connection timeout=0";

polaczenie.Open();

DataTable dtt = new DataTable();
                        
//tu tworze obiekt ktory bedzie przechowywal dane w liscie
Tomato hghg = new Tomato();             
List<Tomato> probbb = new List<Tomato>();
//-------------------------------------------------------
SqlDataReader czytacz;
SqlCommand zapyta;

zapyta = new SqlCommand("tu jest zapytanie - tabela - (nolock) …");

zapyta.Connection = this.polaczenie;

czytacz = zapyta.ExecuteReader();

dtt.Load(czytacz);
int iloscr = dtt.Rows.Count;

//odczyt danych z SQL i zapis do listy
FileStream fs = new FileStream(@"C:\new\ropo.csv", FileMode.Create);
StreamWriter writer = new StreamWriter(fs, Encoding.UTF8);

if (writer != null)
   {
                       writer.WriteLine(@"Kategoria;Kontrahent;Artykul;Faktury;Data;Wartosc            

foreach (DataRow item in dtt.Rows)
{
hghg.ShortName.Add(Convert.ToString(item[0]));
hghg.FullName.Add(Convert.ToString(item[1]));
hghg.ShortName2.Add(Convert.ToString(item[2]));
hghg.FullName2.Add(Convert.ToString(item[3]));
hghg.ShortName3.Add(Convert.ToString(item[4]));                                 hghg.FullName3.Add(float.Parse(Convert.ToString(item[5])));             
}
probbb.Add(hghg);

polaczenie.Close();

writer.Close();
1

bierzesz "tu jest zapytanie - tabela - (nolock) …" i odpalasz w jakimś narzędziu do bazy, które pokaże Ci plan zapytania. Analizujesz plan i na tej podstawie dodajesz indeksy tak aby było szybko.

Pytanie pomocnicze - ile dostajesz rekordów dla zapytania z przedziałem czasowym np. tydzień?

0

Ponieważ wypieprza się na zapytaniu SQL, to kluczowe jest tutaj zapytanie SQL, a nie kod C#. Tymczasem Ty wstawiłeś kod C#, a SQL usunąłeś.

Niektórzy ludzie tak naprawdę nie chcą chyba pomocy. :(

0
  1. Zgodnie z tym co koledzy mówią optymalizacja samego zapytania może dużo dać (ważne jest żeby go nie sklejać string.Formatem/konkatenacją tylko używać parametrów nazwanych to sprawi że SQL zamiast wyliczać ponownie plan zapytania będzie próbował korzystać z istniejącego).
  2. Niezwiązane z twoim problemem ale wpływające na wydajność: Olej DataTable to sprawia że najpierw wszystkie wyniki zapytania są pakowane do pamięci (a zapis do pliku czeka) a potem są z pamięci przewalane do pliku. Używaj while(czytacz.Read()) i będzie git

edit:
co do planu zapytania zanim założysz indeks zastanów się czy nie da się poprzestawiać czegoś w zapytaniu żeby wyliczył się optymalniejszy plan (np. wykorzystujący już istniejące indeksy). Indeksy przyspieszają zapytanie pod które są robione ale spowalniają wszystkie zapytania modyfikujące dane.

0

Niestety problem z zapytaniem polega na tym że nie mogę go znacząco zmienić muszę korzystać z pewnych tabel i widoków(wiem że obciążają zapytanie ale nie mam innej możliwości).
Mogę natomiast zmienić parę rzeczy które wysyłam może ktoś coś zauważy.
A więc: poz.DataSys >= convert(int,convert(datetime,'2014-07-01'))+36163 and poz.DataSys <= convert(int,convert(datetime,'2014-07-17'))+36163 //używam by określić datę w '...' umieszczam zmienną którą wydobywam z dateTimePicker.
Używam również do wydobycia paru danych 'tabela like 'H-%'' próbowałem również tabela in ('234', '237', '64' i tak chyba z 30 różnych warunków') więc to chyba nic nie dało.
W selecie używam również cast(widok_tabeli-36163 as datetime) as Data do wydobycia daty. Używam również (nolock) żeby nie blokować danych.
Niestety muszę do zapytania doklejać parę stringów by określić datę i rodzaj kategorii który chce wybrać użytkownik. Nic więcej w zapytaniu nie ma i co wy na to?
Szogun1987 dzięki za podpowiedz 2 za chwilę to sprawdzę.

0

Nie możesz zmienić logiki zapytania ale może zmienić jej implementację (na tym właśnie polega optymalizacja). Coś wyrzucisz to tab tymczasowej, gdzieś założysz indeks gdzieś zmniejszysz ilość wywołań wolnej funkcji.
@somekind wspominał o użyciu SSIS co też może nie być głupim pomysłem.

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