Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> optymalizacja zapytań i bazy danych
Arek00
post 18.01.2008, 21:44:33
Post #1





Grupa: Zarejestrowani
Postów: 177
Pomógł: 0
Dołączył: 8.11.2005

Ostrzeżenie: (0%)
-----


przeglądając phpmyadmin znalazłem coś takiego:


w jaki sposób zabrać się za usunięcie tych błędów? jak sprawdzić czy zapytanie poprawnie używa indeksów?
Go to the top of the page
+Quote Post
kitol
post 20.01.2008, 12:02:11
Post #2





Grupa: Zarejestrowani
Postów: 162
Pomógł: 26
Dołączył: 19.01.2007

Ostrzeżenie: (0%)
-----


Używając explain:

  1. EXPLAIN SELECT (dalsza część zapytania)


z analizy otrzymanych informacji można wywnioskować co jest nie tak. Generalnie wszystkie kolumny których używamy w JOIN powinny mieć założone indeksy.
Go to the top of the page
+Quote Post
Aztech
post 20.01.2008, 12:36:48
Post #3





Grupa: Zarejestrowani
Postów: 276
Pomógł: 3
Dołączył: 22.10.2003
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Przeczytaj sobie artykuły do których linkowałem w tym poście w szczególności ten z EIOBA.
Go to the top of the page
+Quote Post
Arek00
post 20.01.2008, 13:49:39
Post #4





Grupa: Zarejestrowani
Postów: 177
Pomógł: 0
Dołączył: 8.11.2005

Ostrzeżenie: (0%)
-----


znalazłem takie zapytanie:

  1. SELECT opis_nazwy.id_produktu, opis_nazwy.nazwa
  2. FROM sklep_cennik LEFT JOIN opis_nazwy ON opis_nazwy.id_produktu = sklep_cennik.id_produktu
  3. WHERE opis_nazwy.id_produktu IS NOT NULL AND sklep_cennik.dostepnosc LIKE 'T'
  4. ORDER BY rand( )
  5. LIMIT 9


wynik polecenia explain:

Kod
id|select_type|table       |type|possible_keys     |key    |key_len|ref                            |rows|Extra
1 |SIMPLE     |opis_nazwy  |ALL |PRIMARY           |NULL   |NULL   |NULL                           |4834|Using where; Using temporary; Using filesort
1 |SIMPLE     |sklep_cennik|ref |PRIMARY,dostepnosc|PRIMARY|194    |drupal47.opis_nazwy.id_produktu|1   |Using where


z tego co zdążyłem się dowiedzieć to przy tabeli opis_nazwy też powinien być wykorzystywany klucz. jak to poprawić?
Go to the top of the page
+Quote Post
kitol
post 20.01.2008, 17:57:14
Post #5





Grupa: Zarejestrowani
Postów: 162
Pomógł: 26
Dołączył: 19.01.2007

Ostrzeżenie: (0%)
-----


W zapytaniu zmień:
  1. sklep_cennik.dostepnosc LIKE 'T'

na
  1. sklep_cennik.dostepnosc='T'


Wydaje mi się że:
  1. LEFT JOIN opis_nazwy ON opis_nazwy.id_produktu = sklep_cennik.id_produktu
  2. WHERE opis_nazwy.id_produktu IS NOT NULL

lepiej zamienić na:
  1. RIGHT JOIN opis_nazwy ON opis_nazwy.id_produktu = sklep_cennik.id_produktu


Proponuję takie zapytanie:
  1. SELECT opis_nazwy.id_produktu, opis_nazwy.nazwa
  2. FROM sklep_cennik RIGHT JOIN opis_nazwy ON opis_nazwy.id_produktu = sklep_cennik.id_produktu
  3. WHERE sklep_cennik.dostepnosc='T'
  4. ORDER BY rand()
  5. LIMIT 9


Widzę że tabele są łączone po PRIMARY KEY więc jest OK. Czy id_produktu to INT, czy coś innego?
Poza tym indeks powinien być założony na sklep_cennik.dostepnosc.
Go to the top of the page
+Quote Post
Arek00
post 20.01.2008, 19:47:36
Post #6





Grupa: Zarejestrowani
Postów: 177
Pomógł: 0
Dołączył: 8.11.2005

Ostrzeżenie: (0%)
-----


przy takim zapytaniu:

  1. SELECT opis_nazwy.id_produktu, opis_nazwy.nazwa
  2. FROM sklep_cennik RIGHT JOIN opis_nazwy ON opis_nazwy.id_produktu = sklep_cennik.id_produktu
  3. WHERE sklep_cennik.dostepnosc = 'T'
  4. ORDER BY rand( )
  5. LIMIT 9

wygląda to tak:

Kod
id|select_type|table       |type|possible_keys     |key       |key_len|ref                              |rows|Extra
1 |SIMPLE     |sklep_cennik|ref |PRIMARY,dostepnosc|dostepnosc|8      |const                            |3655|Using where; Using temporary; Using filesort
1 |SIMPLE     |opis_nazwy  |ref |PRIMARY           |PRIMARY   |44     |drupal47.sklep_cennik.id_produktu|1   |Using where


na sklep_cennik.dostepnosc byl zalozony klucz juz wczesniej

nie orientuję się dobrze o co chodzi z tymi kluczami. id_produktu to varchar(20) i jest jako primary.
Go to the top of the page
+Quote Post
kitol
post 20.01.2008, 20:34:09
Post #7





Grupa: Zarejestrowani
Postów: 162
Pomógł: 26
Dołączył: 19.01.2007

Ostrzeżenie: (0%)
-----


Nowe zapytanie na EXPLAIN wygląda lepiej. Possible keys - są to indeksy z których baza może skorzystać. W kolumnie "key" są indeksy które faktycznie wykorzystuje. W drugim przypadku w obu tabelach używa indeksów - "dostepnosc" dla tabeli 'sklep_cennik' oraz PRIMARY dla tabeli opis_nazwy. Powinieneś sprawdzić czy zmniejszył się czas wykonywania zapytania - phpMyAdmin i podobne podają ten czas. Wykonaj zapytania w obu wersjach i porównaj. Sprawdź też czy wyniki obu zapytań są prawidłowe. Identyczne nie będą bo wybierasz rekordy losowe. Funkcja LIKE której wcześniej użyłeś wyklucza sprawdzanie po indeksie dlatego równoznaczne ='T' jest lepsze.  
Go to the top of the page
+Quote Post
Arek00
post 21.01.2008, 00:13:59
Post #8





Grupa: Zarejestrowani
Postów: 177
Pomógł: 0
Dołączył: 8.11.2005

Ostrzeżenie: (0%)
-----


to co podawałem było z mojego komputera. teraz próbuję sprawdzić to samo zapytanie na serwerze zdalnym:

  1. SELECT opis_nazwy.id_produktu, opis_nazwy.nazwa
  2. FROM sklep_cennik RIGHT JOIN opis_nazwy ON opis_nazwy.id_produktu = sklep_cennik.id_produktu
  3. WHERE sklep_cennik.dostepnosc = 'T'
  4. ORDER BY rand( )
  5. LIMIT 9


Kod
id|select_type|table       |type|possible_keys     |key    |key_len|ref                            |rows|Extra
1 |SIMPLE     |opis_nazwy  |ALL |PRIMARY           |NULL   |NULL   |NULL                           |2849|Using temporary; Using filesort
1 |SIMPLE     |sklep_cennik|ref |PRIMARY,dostepnosc|PRIMARY|194    |drupal47.opis_nazwy.id_produktu|1   |Using where


nie wiem dlaczego ale działa inaczej...
Go to the top of the page
+Quote Post
kitol
post 21.01.2008, 09:58:46
Post #9





Grupa: Zarejestrowani
Postów: 162
Pomógł: 26
Dołączył: 19.01.2007

Ostrzeżenie: (0%)
-----


Może jest to kwestia różnicy wersji mySql'a na obu serwerach?? Porównaj również definicję tabeli (typy danych i indeksy)
Go to the top of the page
+Quote Post
Arek00
post 23.01.2008, 00:09:08
Post #10





Grupa: Zarejestrowani
Postów: 177
Pomógł: 0
Dołączył: 8.11.2005

Ostrzeżenie: (0%)
-----


na komputerze mam mysql 5.0.27 a na serwerze zdalnym 5.0.26. struktura i indeksy są identyczne więc to zapytanie powinno być wykonywane tak samo tu i tu.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 2.07.2025 - 16:16