Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [optymalizacja] Select Where IN( Select)
mkozak
post 28.02.2007, 12:09:46
Post #1





Grupa: Zarejestrowani
Postów: 78
Pomógł: 4
Dołączył: 21.03.2005

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


Czesc miszcze od MySql-a,

Mam zagwostkę i pytanie. Here is situation.

Zapytanie :
  1. SELECT count( id ) FROM stats WHERE serviceid
  2. IN ( SELECT id FROM services WHERE name LIKE 'wp%' GROUP BY id)


Tabela stats ma około 70 MB i szczerze powiedziawszy jest kiepsko zoptymalizowana.
Nie starczyło mi cierpliwości, żeby sprawdzić jak długo wykonuje się to zapytanie.

Jeżeli wykonuję je osobno tzn:
  1. SELECT id FROM services WHERE name LIKE 'wp%' GROUP BY id


dostaje 32 rzędy w 0.00 sec

  1. SELECT count( id ) FROM stats WHERE serviceid


dostaje odpowiedź w 0.00 sec

jeżeli wezmę oszukam całą procedurę i wstawie do IN wynik zapytania:
  1. SELECT count( id ) FROM stats WHERE serviceid
  2. IN (60,65,66,67,68,69,70,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,165,166,167,271)


dostaję odpoeidź w 0.42 sec

Pytanie - dlaczego wykonanie dwóch selectów na raz trwa nieskończenie dłużej niż takie "oszukanie" zapytanie z IN-em??

Jak można przekonać optymalizera MySQL-owego do poprwnej interpretacji??


--------------------
==============================================
Bo ja jestem Wróbelek Htmlek
==============================================
Go to the top of the page
+Quote Post
dr_bonzo
post 28.02.2007, 12:36:50
Post #2





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


A mozesz dac strukture bazy, z indexami?


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Sh4dow
post 1.03.2007, 13:51:18
Post #3





Grupa: Zarejestrowani
Postów: 569
Pomógł: 0
Dołączył: 17.08.2003
Skąd: Dąbrowa Górnicza

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


z jednej strony prawdopodobnie brakuje indeksów, ale z drugiej prawdopodobnie tworzenie tymczasowej tablicy zamula serwer. pewnie robi jakis zlaczenie tablic zeby pozniej wybrac z nich dane. Chociaz moge sie mylic.


--------------------
Warsztat: Linux: PHP, MySQL, Apache, NetBeans, C++, Qt-Creator
Użytkownik, słowo którego specjaliści IT używają, gdy chcą powiedzieć idiota
Zarządzaj swoim budżetem domowym
Go to the top of the page
+Quote Post
SongoQ
post 1.03.2007, 14:17:31
Post #4





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

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


Sprawdz tak:

  1. SELECT count( services.id ) FROM stats, services WHERE stats.serviceid = services.id AND name LIKE 'wp%'


I teraz tak index na stats.serviceid no i oczywiscie id sa jako PK. Jesli tabele sa jako InnoDB to musisz zrobic relacje. Podaj typ pola name czy to jest varchar czy cos wiekszego. Jesli to jest cos wiekszego to niestety troche trzeba pokombinowac.

Napisz co daje explain dla tego zapytania.

Mozesz tez zamiast services.id dac * ale ine powinno byc roznicy


--------------------
Go to the top of the page
+Quote Post
mkozak
post 2.03.2007, 12:53:47
Post #5





Grupa: Zarejestrowani
Postów: 78
Pomógł: 4
Dołączył: 21.03.2005

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


Cytat(Sh4dow @ 1.03.2007, 13:51:18 ) *
z jednej strony prawdopodobnie brakuje indeksów, ale z drugiej prawdopodobnie tworzenie tymczasowej tablicy zamula serwer. pewnie robi jakis zlaczenie tablic zeby pozniej wybrac z nich dane. Chociaz moge sie mylic.



No i to jest ciekawa teoria, bo jeżeli staram się wysterować optymalizera dając SQL_SMALL_RESULT co teoretycznie zmniejsza wielkość tablicy - nie daje żadnego efektu.

Z poprzednimi ripostami iż "brak indexów, albo coś" jakoś się nie zgodzę - przypominam iż osobno zapytania wykonują się bardzo szybko - a na obu tabelach pola id są indexami.

A name jest typu varchar(20)

Ktoś tam prosił o explain
  1. +----+--------------------+----------+------+---------------+------+---------+------+--------+-------------+
  2. | id | select_type | TABLE | type | possible_keys | KEY | key_len | ref | rows | Extra |
  3. +----+--------------------+----------+------+---------------+------+---------+------+--------+-------------+
  4. | 1 | PRIMARY | stats | ALL | NULL | NULL | NULL | NULL | 458920 | USING WHERE |
  5. | 2 | DEPENDENT SUBQUERY | services | ALL | NULL | NULL | NULL | NULL | 275 | USING WHERE |
  6. +----+--------------------+----------+------+---------------+------+---------+------+--------+-------------+


  1. SELECT count( services.id ) FROM stats, services WHERE stats.serviceid = services.id AND name LIKE 'wp%'


Natomiast to zapytanie wykonuje sie bardzo optymalnie - 0.17 sec - dzieki smile.gif - ale jak wyjaśnić tą zagwostkę iż z sub selectem jest niewspółmiernie dłużej niż z podanymi wartosciami.

Ten post edytował mkozak 2.03.2007, 13:05:29


--------------------
==============================================
Bo ja jestem Wróbelek Htmlek
==============================================
Go to the top of the page
+Quote Post
SongoQ
post 2.03.2007, 13:37:40
Post #6





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

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


O ile pamietam to dla kazdej wartosci bedzie jechal podzapytanie. Jest kilka ksiazek na ten temat z podanymi przykladami kiedy warto stosowac IN a kiedy to jest wrecz zabronione


--------------------
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: 13.06.2025 - 02:32