![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 68 Pomógł: 0 Dołączył: 21.10.2007 Ostrzeżenie: (0%) ![]() ![]() |
Dlaczego poniższe zapytanie idzie w minuty tzn trwa do kilku minut w tabeli tr_wydanie jest 800 recordów.
Jest index na id, i na kontrahent_id wg mnie i bez tych indexów powinno chodzić szybko.
tabela wygląda tak
Po początkowym wgraniu dumpa chodzi te zapytanie bardzo szybko. Po jakimś czasie trwa kilka minut i już tak zawsze jest. Silnik MyISAM. Ten post edytował pogdan 8.10.2013, 15:16:53 |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 890 Pomógł: 339 Dołączył: 14.12.2006 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
IMO trochę przekombinowane to zapytanie. Ja bym raczej zrobił 3 oddzielne, bo MySQL lubi się zaplątać przy zagnieżdżonych podzapytaniach.
Co wypluwa Explain?
[edit] No i pierwsze co to wypadałoby zrobić index:
[edit] Poprawiłem KEY --> INDEX Ten post edytował sowiq 8.10.2013, 21:32:17 |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 68 Pomógł: 0 Dołączył: 21.10.2007 Ostrzeżenie: (0%) ![]() ![]() |
ten index to dodatkowo? czy index wydanie_kontrahent_id usunąć Ten post edytował pogdan 8.10.2013, 15:49:55 |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 1 890 Pomógł: 339 Dołączył: 14.12.2006 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Spróbuj dodać indeks na pola id, id_kontrahenta i zobacz czy będzie poprawa. Jeśli nie, to tak jak pisałem - lepiej chyba rozbić to na 3 oddzielne zapytania.
|
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 1 933 Pomógł: 460 Dołączył: 2.04.2010 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 68 Pomógł: 0 Dołączył: 21.10.2007 Ostrzeżenie: (0%) ![]() ![]() |
tak naprawdę to potrzebuję czegoś takiego gdzie 'kiedy' jest polem typu 'datetime' i sensu nabier dopiero jak jest coś wiećej niż id czyli np. jeszcze name możę teraz już nie bezie take masło maślane.
i tak naprawdę jest to podzapytanie to zapytania już własciwego ale już tu długo trwa. natomiast samo
trwa dość szybko. poniżej secundy a nawet 0.00sec pokazuje. Zupełnie nie rozumiem ma już id wybrane to co ma za problem żeby wybrać po indexie primary_key rekordy (już te z name ) Ja na mój gust to się baza danych sypie. i pewnie sowiqa pomoc zastosuję. |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 1 933 Pomógł: 460 Dołączył: 2.04.2010 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
Spytam jeszcze o jedno, co chcesz osiągnąć, tj. jakie rekordy pobrać? Bo że zapytanie jest nieoptymalne to wiadomo i od jego optymalizacji bym właśnie zaczął. Powiedz co chcesz pobrać, a spróbuję pomóc.
No i pierwsze co to wypadałoby zrobić index:
Dodanie klucza nie wpłynie na szybkość wyszukiwania... Tutaj należałoby zastosować INDEX.
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 68 Pomógł: 0 Dołączył: 21.10.2007 Ostrzeżenie: (0%) ![]() ![]() |
sprawa jest rzeczewiscie dziwna bo te zapytanie , robi to samo , i już zasuwa szybko (być może ustanie ta szybkość po jakimś czasie tak przeczuwam)
Strange mysql rules Ten post edytował pogdan 8.10.2013, 16:58:39 |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 1 890 Pomógł: 339 Dołączył: 14.12.2006 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 68 Pomógł: 0 Dołączył: 21.10.2007 Ostrzeżenie: (0%) ![]() ![]() |
Dzięki sowiq i b4rt3kk na razie mi to chodzi jako join a nie jako podzapytanie.
Czym się różni index (id, kontrahent_id) od dwóch indexów odzielnie id i kontrahent_id . |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 282 Pomógł: 89 Dołączył: 12.04.2011 Ostrzeżenie: (0%) ![]() ![]() |
Dla mysql nie ma znaczenia które z poniższych składni zastosujemy:
To wszystko dla normalnego indeksu da nam dokładnie ten sam rezultat. Istnieją drobne różnice, ale w naszym przypadku nie mają znaczenia. Jeśli ktoś nie wierzy, proponuję tworzenie i kasowanie indeksu każdą z tych trzech metod i sprawdzanie SHOW INDEXES FROM t; Indeks na kilku kolumnach, czyli na przykład (kontrahent_id, kiedy) ma w sobie zawartość wszystkich tych kolumn, posortowaną najpierw według kontrahent_id a później dla takich samych kontrahentów według kiedy. Normalne indeksy, niezależnie od ilości kolumn ( pomijamy fulltext, spatial itp) są typu BTREE, chodzi o to, by przyspieszyć wyszukiwanie rekordów na podobnej zasadzie jak wyszukiwanie binarne przyspiesza na posortowanym zbiorze. Indeksy wielokolumnowe zawierają w sobie funkcjonalność indeksów dla kolumn z lewej strony, czyli mając taki podwójny nie ma sensu tworzyć następnego indeksu na pojedynczej kolumnie (kontrahent_id). Nie pomagają natomiast dla kolumn po prawej stronie, czyli indeks na pojedyncza kolumnę (kiedy) wciąż może być potrzebny. Jeżeli chodzi o zapytanie, które jak się domyślam ma znajdować dla każdego kontrahenta ostatni rekord według daty w kolumnie kiedy, a jeśli takich rekordów jest więcej to według najwyższego id, przy czym brać pod uwagę tylko rekordy spełniające warunek wydanie>0, to proponowałbym przy założeniu, że id jest kluczem primary, mamy indeksy na (kontrahent_id, id) oraz (kiedy, id), a większość rekordów spełnia warunek wydanie>0, takie rozwiązanie:
W tym przypadku indeks (kontrahent_id, id) będzie wykorzystywany do połączenia z correlated subquery, natomiast indeks (kiedy,id) do ORDER BY kiedy DESC, id DESC, otrzymujemy dość czysty explain:
Na testowej bazie z losowymi rekordami 1k kontrahentów, dla każdego po 100 wpisów, czyli w sumie 100000 rekordów zapytanie działa około 2s, co przy tej strukturze danych i warunkach zapytania jest dość dobrym wynikiem. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 27.09.2025 - 03:36 |