Temat: [MySQL] Optymalizacja zapytania - mam sporo informacji,...

Cześć, mam takie oto zapytanie:


SELECT DISTINCT T.NumerRef
FROM
m_transporty_miejsca AS TM LEFT JOIN
m_transporty AS T ON (T.ID=TM.ID_transport)
WHERE
1 AND
(AnulowanyFE2='0' OR DateRealizacji>='2011-06-30') AND
1 AND
T.Odleglosc>='0' AND
T.Odleglosc<='99' AND
T.ImportFE='1' AND
(
(T.STATUS='zaksięgowane w SAP' AND (T.DataDostarczenia IS NULL AND T.ID_przewoznik='72'))
OR
(T.STATUS='przedstawiony' AND (T.Miejsce='akt'))
OR
(T.STATUS='gielda' AND (T.Miejsce='akt' AND T.Gielda='1'))
OR
(T.Miejsce='akt' AND T.ID_przewoznik='72')
)
ORDER BY T.ID


Tabela m_transporty_miejsca 200 000 rekordów
Tabela m_transporty 100 000 rekordów
raczej małe ilości.

Zapytanie wykonuje się około 0,8s (średnia z 20pomiarów).
Jeśli usunę ostatni warunek w klauzuli WHERE:
( Miejsce='akt' OR (STATUS='zaksięgowane w SAP' AND DataDostarczenia IS NULL) ) 


a szczególnie
 OR (STATUS='zaksięgowane w SAP' AND DataDostarczenia IS NULL) 


wówczas czas zapytania spada do 0,03 (średnia z 20pomiarów)
Indexy jakie min. mam pozakładane na tabelę m_transporty to:
ImportFE1: (ImportFE)
ImportFE2: (ImportFE+Miejsce)
ImportFE3: (ImportFE+Status+DataDostarczenia)

EXPLAIN tego zapytania wskazuje, że użyty jest indeks "ImportFE1"

Proszę o pomoc w optymalizacji.Tomek Łos edytował(a) ten post dnia 10.07.11 o godzinie 12:55

konto usunięte

Temat: [MySQL] Optymalizacja zapytania - mam sporo informacji,...

dodaj sobie indeks tylko na pole DataDostarczenia
Grzegorz D.

Grzegorz D. PL/SQL Developer

Temat: [MySQL] Optymalizacja zapytania - mam sporo informacji,...

Pierwsze co mi się rzuciło w oczy to ten kawałek kodu:

T.Odleglosc>='0' AND
T.Odleglosc<='99' AND
T.ImportFE='1' AND

Jeżeli Odległość i ImportFE są typu numerycznego, to nie powinieneś stawiać do porównania stringa.
Przynajmniej w Oraclu oznacza to zawsze niejawną konwersję typów - myślę, że w MySQLu jest podobnie.

Poza tym, przeglądając pobieżnie zapytanie - czy potrzebujesz LEFT JOINa? Czy zwykły INNER JOIN w tym przypadku nie jest wystarczający? Ograniczasz m_transporty do takich wierszy, które mają jakieś wyniki - stąd moje pytanie.Grzegorz Drzymała edytował(a) ten post dnia 10.07.11 o godzinie 13:19

Temat: [MySQL] Optymalizacja zapytania - mam sporo informacji,...

Przemysław R.:
dodaj sobie indeks tylko na pole DataDostarczenia
Mam :(
Grzegorz Drzymała:
Jeżeli Odległość i ImportFE są typu numerycznego, to nie powinieneś stawiać do porównania stringa.
Przynajmniej w Oraclu oznacza to zawsze niejawną konwersję typów - myślę, że w MySQLu jest podobnie.
Odległość - numeryczne, ImportFE - ENUM (0/1)

Czy dla pól, które mogą przyjąć tylko wartości 0/1/2/3 - lepiej jest użyć (small)int czy Enum (0/1/2/3)?
Czy konwersja ENUM->SMALLINT nie sprawi mi kłopotu (utrata danych/kłopoty w zapytaniach?)

Grzegorz Drzymała:
Poza tym, przeglądając pobieżnie zapytanie - czy potrzebujesz LEFT JOINa? Czy zwykły INNER JOIN w tym przypadku nie jest wystarczający? Ograniczasz m_transporty do takich wierszy, które mają jakieś wyniki - stąd moje pytanie.
Tak - warto to sprawdzićTomek Łos edytował(a) ten post dnia 10.07.11 o godzinie 14:28
Tomasz Zadora

Tomasz Zadora programuję

Temat: [MySQL] Optymalizacja zapytania - mam sporo informacji,...

Dodam od siebie (bez dokładnego analizowania zapytania), że możesz podpowiadać MySQLow jakich indeksów powinien używać - planner MySQLa nie zawsze dobiera je najlepiej z puli dostępnych, zobacz: http://dev.mysql.com/doc/refman/5.1/en/index-hints.html

Po drugie - jeżeli używasz DISTINCT to prawdopodobnie mógłbyś zrobić inną/lepszą strukturę danych (pod kątem szybkości zapytania) rozłożoną na większą ilość tabel.

Po trzecie - jeżeli powtarzasz często te same zapytania (np. w środowisku www) to prawdopodobnie pomoże cache: albo ten wewnętrzny MySQL-a (query cache), albo możesz skorzystać z memcached i innych mechanizmów.Tomasz Zadora edytował(a) ten post dnia 11.07.11 o godzinie 00:30
Krzysztof Białkowski

Krzysztof Białkowski Software Developer
(C# .NET)

Temat: [MySQL] Optymalizacja zapytania - mam sporo informacji,...

Tak na szybko bo jeszcze kawy nie piłem ; )


T.STATUS='zaksięgowane w SAP'


Uważam, że warto te statusy(bo pojawia się kilka) wrzucić do jakieś tabeli słownikowej i pytać po id'kach.

To samo można tutaj :

T.Miejsce='akt'


Ew jeśli miejsc jest mało to typ kolumny ENUMKrzysztof Białkowski edytował(a) ten post dnia 13.07.11 o godzinie 10:07

Następna dyskusja:

Optymalizacja zapytania / t...




Wyślij zaproszenie do