Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Przyspieszenie zapytania - pytanie
Forum PHP.pl > Forum > Bazy danych > MySQL
Ardo

Może mi doradzicie, mam takie zapytanie, czy da się jakoś te zapytanie inaczej zapisać, by przyspieszyć działanie, może jakaś inna forma zapisu.
Macie pomysły, będe wdzięczny za wszelkie sugestie, rady

  1. SELECT * FROM ciezarowe a
  2. INNER JOIN waluta AS s ON (a.odWaluta = s.walutaId )
  3. INNER JOIN kwota AS p ON (a.odKwota = p.kwotaId )
  4. INNER JOIN tdostawcze AS k ON (a.odType = k.typeId )
  5. INNER JOIN state AS t ON (a.odState = t.stateId )
  6. INNER JOIN rdostawcze AS m ON (a.odRodzaj = m.id )
  7. INNER JOIN uszkodzony AS n ON (a.odUsz = n.uszId )
  8. INNER JOIN kategoria AS o ON (a.odKategoria = o.katId )
  9. INNER JOIN cmarka AS f ON (a.odMarka = f.markaId )
  10. INNER JOIN region AS r ON (a.odRegion = r.regionId )
  11. INNER JOIN stan AS w ON (a.odStan = w.stanId )
  12. INNER JOIN rodzaj AS z ON (a.odPaliwo = z.rodzajId )
  13. INNER JOIN jednostkaMocy AS x ON (a.odMocr = x.mocId )
  14. INNER JOIN STATUS AS c ON (a.odStatus = c.statId )
  15. INNER JOIN faktura AS g ON (a.odFaktura = g.vatId )
  16. INNER JOIN region AS u ON (a.odKrajpochodzenia = u.regionId )
  17. INNER JOIN region AS v ON (a.odKrajrejestracji = v.regionId )
  18. WHERE a.odDate = '$data'
rocktech.pl
Witam.

Wklej wynik zapytania dodając EXPLAIN.

  1. EXPLAIN SELECT * FROM ciezarowe a ...


Sephirus
1. przede wszystkim 'SELECT *' to zabójstwo przy takim zapytaniu - może dasz radę nieco okroić kolumny do tych które potrzebujesz (ogromna tabela tymczasowa się robi do tego - to może trwać)

2. Zapytanie pod względem złączeń wydaje się optymalne. Nie ma w nim ani ORDER BY ani GROUP BY, które wymusiły by dodatkowe sortowanie - co sprawia, że nie ma na to opóźnienia. Jedyne co zastanawia to czy wszystkie pola użyte w klauzuli ON i WHERE mają odpowiednie indeksy.

3. Kiedy wykonujesz to zapytanie? Jak często? Jakie jest obciążenie bazy? Jeśli działasz na MyISAM i to się wykonuje często to mogą być duże opóźnienia przez blokowanie tabel. Powinno to być na InnoDB.

4. Wydaje mi się, że niektóre z tabel są dodane (dołączne) na siłę. Przykładowo rozumiem że `Uszkodzenia`, `Stan` itp to bardziej słowniki. Możesz równie dobrze pobierać słowniki całe (jeśli nie są duże) oddzielnymi zapytaniami i je cacheować. Następnie przy wyświetlaniu rekordu po prostu je wyświetlać. Może się to okazać dużo wydajniejsze niż masa złączeń.

5. Jakiej wielkości są te tabele? Jaki jest rząd wielkości liczby rekordów?
Ardo
juz obiasniam te zapytanie służy do stworzenie XML, musze mieć te elementy bo te elementy musze załadować wszystkie do XML.
te zapytanie będzie wykonywane tylko wtedy kiedy będzie wykonywany plik exportu

Jesli chodzi o wynik:

  1. id select_type table type possible_keys key key_len ref rows Extra
  2. 1 SIMPLE p ALL PRIMARY NULL NULL NULL 2
  3. 1 SIMPLE a ALL NULL NULL NULL NULL 3 Using where
  4. 1 SIMPLE w eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odStan 1
  5. 1 SIMPLE x eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odMocr 1
  6. 1 SIMPLE n eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odUsz 1
  7. 1 SIMPLE g eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odFaktura 1
  8. 1 SIMPLE s eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odWaluta 1
  9. 1 SIMPLE c eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odStatus 1
  10. 1 SIMPLE k eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odType 1
  11. 1 SIMPLE z eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odPaliwo 1
  12. 1 SIMPLE o eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odKategoria 1
  13. 1 SIMPLE r eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odRegion 1
  14. 1 SIMPLE t eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odState 1
  15. 1 SIMPLE m eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odRodzaj 1
  16. 1 SIMPLE f eq_ref PRIMARY PRIMARY 4 webnet_mototest.a.odMarka 1
  17.  
  18.  
rocktech.pl
Witam.

Od razu widać ze brak indeksów na tabelach.

  1. ALTER TABLE `waluta`
  2. ADD INDEX `Index_walutaId ` (`walutaId ` ASC) ;
  3. ALTER TABLE `kwota`
  4. ADD INDEX `Index_kwotaId ` (`kwotaId ` ASC) ;
  5. -- i analogiczne dla całej reszty


Zerknij na PROCEDURE ANALYSE.

  1. SELECT * FROM ciezarowe PROCEDURE ANALYSE(10, 2000);
  2. -- analogicznie dla reszty tabel


Niech nie będzie dla ciebie wyrocznią np (ENUM smile.gif ) ale pozwoli ci zoptymalizować trochę tabele.
Ardo
kazda tabela ma index. , wiec nie bardzo rozumie co masz na mysli , mówiąc że tabele nie mają indexu.
Sephirus
Chodzi o główną tabelę jak widać. Czy jej wszystkie pola, które używasz w JOINach mają indeks?


np.:

Kod
INNER JOIN rdostawcze AS m ON (a.odRodzaj = m.id )


Czy a.odRodzaj ma indeks?
Ardo
dzieki za wskazówki


tak wszyskie tabele mają indeksy tylko nie nazwane id a np markaId uszId
o to pytasz?
Sephirus
Puść

  1. SHOW CREATE TABLE ciezarowe


i wrzuć dla pewności wink.gif
Ardo
wynik:


CREATE TABLE `ciezarowe` ( `odId` int(11) NOT NU...
sazian
chodzi o to
Kod
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra    
1    SIMPLE    a    ALL    NULL    NULL    NULL    NULL    3    Using where

w kolumnach possible_keys i key masz NULL czyli żaden indeks nie został użyty dla tabeli "a", a konkretnie dla któreś z kolumn użytej w złączeniu


odnoszę dziwne wrażenie że te wszystkie tabele(a przynajmniej większość) są w relacji 1:1, jeśli tak to lepiej je zapisać w jednej tabeli
Ardo
w kolumnach possible_keys i key masz NULL czyli żaden indeks nie został użyty dla tabeli "a", a konkretnie dla któreś z kolumn użytej w złączeniu



1.) ale czy musi być index wypisany dla tabeli "a" jak to jest główna tabela i główny index tej tabeli,
index tej tabeli głownej jest dla rekordu (czyli ogłoszenia ), wiec jakim celu index tabeli „a” ma być użyty dla jakiejs kolumny? nie rozumie twojego toku myślenia.

2.) Głowna tabela "a" - to ogłoszenia –Index tej tabeli to rekord
tabela ta zawiera indeksy innych tabel np (kraj , region, stan, marka , itp) i jak te elementy miały by być w jednej tabeli wypisane? nie rozumie tego myślenia również

sazian
prawdopodobnie chodzi o a.odDate

brak indeksu powoduje że trzeba przeszukać wszystkie rekordy.
Załóżmy że w tabeli masz 1000 rekordów i tylko 5 z nich spełnia warunek w WHERE
Jeśli na kolumnie jest indeks zostanie przeszukane tylko 5 rekordów
Jeśli nie ma indeksu zostanie przeszukane 1000 rekordów

oczywiście nie popadaj w paranoję i nie nakładaj indeksów na wszystkie kolumny smile.gif
Najlepiej obserwować EXPLAIN i jeśli w kolumnie rows będą się pojawiały duże liczby to wtedy trzeba myśleć jak to dodatkowo ograniczyć
Firebright
Cytat
2.) Głowna tabela "a" - to ogłoszenia –Index tej tabeli to rekord
tabela ta zawiera indeksy innych tabel np (kraj , region, stan, marka , itp) i jak te elementy miały by być w jednej tabeli wypisane? nie rozumie tego myślenia również


Mylisz chyba indeks z identyfikatorem. Poczytaj trochę o indeksach w bazach danych, szybko załapiesz o czym piszą koledzy.
Ardo
sazian masz racje z tym --> a.odDate
ok dzieki nie zauważyłem tego.



To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.