![]() |
![]() |
![]()
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: 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: 14.10.2025 - 21:41 |