2011-10-24 20 views
5

Próbowałem dowiedzieć się, co jest nie tak z zestawem zapytań, które mam i jestem po prostu zdezorientowany w tym momencie.Zapytania MySQL są szybkie, gdy są uruchamiane bezpośrednio, ale bardzo wolno, gdy są uruchamiane jako przechowywane proc.

Powinien być przechowywany w procedurze, która jest wywoływana przez aplikację GUI.

Jest tylko jeden „drobny” problem, to pierwszy prosty UPDATE, wówczas INSERT użyciu SELECT z podselekcji i wreszcie inny UPDATE. Razem wykonując te zapytania ręcznie uzyskuję całkowity czas wykonania 0.057s, niezbyt odrapany.

Teraz, próbuję utworzyć procedurę składowaną z tymi zapytaniami i pięcioma zmiennymi wejściowymi, uruchomię tę procedurę i przy pierwszej próbie zajęło ona 47.096 z kolejnymi wywołaniami do niej, pokazując podobne czasy wykonania (od 35 do 50). Uruchamianie poszczególnych zapytań z Workbench MySQL nadal pokazuje czasy wykonania poniżej 0.1s

Naprawdę nie ma nic wymyślnego w tych pytaniach, więc dlaczego procedura składowana trwa wieczność, aby wykonać, podczas gdy zapytania same weźmieją ułamek sekundy? Czy istnieje jakiś rodzaj specyficzności MySQL, którego tutaj brakuje?

Dodatkowe wyniki badań:

Wydaje się, że jeśli uruchomię zapytań w MySQL Workbench ale zamiast używać zmiennych po prostu umieszczenie wartości zmiennych w kwerendach działa tak samo wolno jak procedura przechowywana. Tak więc próbowałem zmienić procedurę przechowywaną, aby używać tylko wartości statycznych zamiast zmiennych i nagle działało to niesamowicie szybko. Wygląda na to, że z jakiegoś powodu użycie zmiennej powoduje, że działa ona bardzo wolno (na przykład pierwsze zapytanie o numer UPDATE dotyczy przyjmowania wartości 0,98 z trzema zmiennymi do 0,04-0,05, gdy używam wartości zmiennych bezpośrednio w zapytaniu, niezależnie od tego, czy jest to w procedurze przechowywanej lub bezpośrednio w zapytaniu).

Problem polega nie na procedurze przechowywanej, jest to coś związanego z moim użyciem zmiennych (co jest nieuniknione).

+0

Musielibyśmy zobaczyć kod. Pierwsze dzikie przypuszczenie byłoby czymś dziwnym, co robisz w deklarowaniu/obsłudze zmiennych ... ale to całkowicie * dzikie * odgadnięcie bez zobaczenia jakiegoś kodu. –

+0

Jak już powiedziałem, bardzo proste zapytania, które działają naprawdę szybko, po prostu 'UPDATE table SET column = zmienna WHERE inna kolumna> = inna zmienna LUB inna kolumna = yetanothervar' type stuff. Zmienne są zadeklarowane w zwykłym formularzu 'IN varname COLUMNTYPE (SIZE)' jako parametry procedury składowanej. To, co mnie oszałamia, polega na tym, że nie ma w tym nic dziwnego ani powolnego (i tak, unikam pokazywania kodu z powodu mojego szefa, który prawdopodobnie jest zirytowany, że to robię). – mludd

+0

Mogę wspomnieć, że usunięcie wszystkich prócz pierwszego zapytania "UPDATE" (które samo zajmuje mniej niż 0.05s do uruchomienia, a następnie uruchomienie zapisanego procesu nadal daje czas wykonania około 1 s, a powyższy komentarz jest dość trafnym opisem tego, jak kompleks, że 'UPDATE' jest ... – mludd

Odpowiedz

0

Rozpatrzenie bardzo interesującego i ważnego pytania. Znalazłem this discussion z niektórych powodów, że procedura składowana może być powolna. Byłbym zainteresowany reakcjami czytelników na to.

Główne zalecenie, które wziąłem z wymiany: pomaga dodać więcej indeksów.

+0

Twoja odpowiedź tutaj miała martwy link, poprawiłem go najlepiej, jak mogłem, ale musiałem odwołać się do archive.org Żaden z" duplikatów "źródeł, które widziałem, nie zawierał dodatków Ronalda Bradforda. –

0

Ponieważ nie chciałem tracić zbyt wiele czasu na próbę odkrycia, dlaczego używanie zmiennych w moich procedurach przechowywanych sprawia, że ​​są one bardzo powolne, postanowiłem zastosować poprawkę, którą niektórzy ludzie uznają za dość brzydką. Po prostu wykonałem każde zapytanie bezpośrednio z warstwy dostępu do danych mojej aplikacji. Nie jest to najładniejsza metoda (ponieważ wiele innych rzeczy dla tej aplikacji korzysta z procedur zapisanych w bazie), ale działa i teraz użytkownik nie musi czekać 40+ sekund na pewne czynności, które zdarzają się niemal natychmiast.

Tak naprawdę nie jest to rozwiązanie ani wyjaśnienie tego, co się dzieje, ale przynajmniej działa.

3

Miałem podobny problem. Uruchamianie rutyny mysql było okropnie powolne. Ale współpracownik mi pomógł. Problem polegał na tym, że AUTOCOMMIT był prawdziwy; Tak więc każda wstawka do i wybierz tworzyła kompletną transakcję. Potem uruchomić moją rutynę z

SET autocommit=0; 

na początku i

SET autocommit=1;      

na końcu. Wydajność poszła od prawie 500s do 4s

5

Miałem ten sam problem. Po badaniu przez chwilę odkryłem, że problemem jest kwestia sortowania, podczas gdy MySQL porównywał tekst.

TL; DR: tabela została utworzona w jednym sortowaniu, podczas gdy MySQL "uważał", że zmienna była w innym zestawieniu. Dlatego MySQL nie może korzystać z indeksu przeznaczonego dla zapytania.

W moim przypadku, tabela została utworzona z (latin1, latin1_swedish_ci) zestawień. Aby MySQL użyć indeksu, musiałem zmienić klauzulę where w procedurze przechowywanej od

UPDATE ... WHERE mycolumn = myvariable 

do

UPDATE ... WHERE mycolumn = 
     convert(myvariable using latin1) collate latin1_swedish_ci 

Po zmianie, procedura przechowywana wyglądał mniej więcej tak:

CREATE PROCEDURE foo.'bar'() 
    BEGIN 
     UPDATE mytable SET mycolumn1 = variable1 
     WHERE mycolumn2 = 
      convert(variable2 using latin1) collate latin1_swedish_ci 
    END; 

gdzie (latin1, latin1_swedish_ci) jest taka sama Colla z utworzoną tabelą tableA.

Aby sprawdzić, czy MySQL używa indeksu lub nie, można zmienić procedurę przechowywaną, aby uruchomić oświadczenie explain jak następuje:

CREATE PROCEDURE foo.'bar'() 
    BEGIN 
     EXPLAIN SELECT * FROM table WHERE mycolumn2 = variable2 
    END; 

W moim przypadku, wynik explain wykazały, że nie ma indeksu użyto podczas wykonanie zapytania.

Należy pamiętać, że MySQL może używać indeksu podczas uruchamiania samego zapytania, ale nadal nie będzie używać indeksu dla tego samego zapytania w procedurze przechowywanej, co być może dlatego, że w jakiś sposób MySQL widzi zmienną w innym zestawieniu.

Więcej informacji na temat problemu sortowania można znaleźć tutaj: http://lowleveldesign.wordpress.com/2013/07/19/diagnosing-collation-issue-mysql-stored-procedure/ Powrót do góry link: http://www.codeproject.com/Articles/623272/Diagnosing-a-collation-issue-in-a-MySQL-stored-pro

0

coś, czego zabrakło dziś sprawia, że ​​procedury powolne, nawet gdy działają bardzo szybko, jak bezpośrednich zapytań w poprzek, to posiadające nazwy parametrów (lub prawdopodobnie zmienne), które są takie same jak nazwy kolumn. Krótka wersja to: nie używaj nazwy parametru, która jest taka sama jak jedna z kolumn w zapytaniu, w którym będzie używana. Na przykład, jeśli dysponujesz polem o nazwie account_id i parametrem o tej samej nazwie, zmień go na wartość podobną do in_account_id, a czas działania może wynosić od kilku sekund do setnych części sekundy.

Powiązane problemy