Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Usunięcie warunku powoduje 200-krotne spow
msulik
post 2.04.2003, 00:37:18
Post #1





Grupa: Zarejestrowani
Postów: 83
Pomógł: 0
Dołączył: 31.03.2002
Skąd: Toruń

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


Doznałem dzisiaj szoku. Mam dwie tabele:
Kod
CREATE TABLE tabA (

  id int(10) unsigned NOT NULL auto_increment,

  txt text NOT NULL,

  PRIMARY KEY  (id)

) TYPE=MyISAM;





CREATE TABLE tabB (

  id int(10) unsigned NOT NULL auto_increment,

  blobek mediumblob,

  PRIMARY KEY  (id)

) TYPE=MyISAM;

Wstawiłem tam takie dane, że w każdym wierszu w polu blobek jest ten sam tekst rozmiaru 51208 bajtów, czyli nie mało winksmiley.jpg Natomiast długość danych w polu txt nie przekracza kilkunastu znaków. Obie tabele mają po 1040 rekordów, a cała tabela tabB zajmuje około 51 MB.

Fajnie.

Wywołuję dwa złośliwe zapytania:
nr 1:
Kod
SELECT

    COUNT(tabA.txt)

FROM

    tabA,

    tabB

WHERE

    (

  tabA.id = tabB.id

  AND

  tabA.txt LIKE '%a b c'

  AND

  tabA.txt LIKE '%xyz%'

  AND

  tabB.blobek LIKE '%ala ma kota i psa%'

    );

oraz nr 2 (usunięte zostały tylko warunki na pole txt):
Kod
SELECT

    COUNT(tabA.txt)

FROM

    tabA,

    tabB

WHERE

    (

  tabA.id = tabB.id

  AND

  tabB.blobek LIKE '%ala ma kota i psa%'

    );


Niby fajnie. Dane są ustawione tak, że tekst "ala ma kota i psa" znajduje się w każdym rekordzie TYLKO na samym końcu pola blobek, również warunki na pole txt ZAWSZE są spełnione. Oba zapytania zwracają to co trzeba, tzn oczekiwany przeze mnie wynik.

Problem.
Zapytane numer 2 jest mniej restrykcyjne, tzn. warunki są słabsze, a więc teoretycznie powinno się wykonać szybciej.

Zapytanie numer 1 (to bardziej złożone) wykonuje się około 0.05 sekundy (pięć setnych), a zapytanie numer 2 (to mniej złożone) wykonuje się w około 10.7 (dziesięć i siedem setnych) sekundy (czyli około 200 razy wolniej niż zapytanie numer 1).

Rozumiem, że statystyka statystyką i błąd jakiś jest dopuszczalny. Rozumiem też, że w zasadzie (w granicach jakiegoś rozsądnego błędu) nie powinna wystąpić zmiana czasu wykonania zapytania po usunięciu warunków na pole txt. Rozumiem też, że w MySQL jest optymalizator, chociaż imho w tym przypadku niewiele może zdziałać, bo warunki na pole txt zawsze są spełnione, więc warunek na blobek i tak musi zostać sprawdzony.

Nie rozumiem jednak, dlaczego czas wykonania zapytania w ogóle wzrósł i dlaczego aż tak drastycznie. Czy ktoś może mi to wyjaśnić? smile.gif Może to jakiś spisek? Za usunięcie prawdy słono płaci się straconym czasem? :mrgreen:

P.S. Nie, nie zwariowałem, sprawdzałem to kilka razy :mrgreen:


--------------------
misiu | chór

"Zdeterminowany programista potrafi stworzyć fatalny kod w każdym języku"
Allen Holub
Go to the top of the page
+Quote Post
zalew
post 2.04.2003, 02:19:16
Post #2





Grupa: Zarejestrowani
Postów: 407
Pomógł: 0
Dołączył: 24.10.2002
Skąd: warszawa

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


na moje oko to ten warunek
Kod
tabA.txt LIKE '%a b c'

      AND

      tabA.txt LIKE '%xyz%'


spowodowal ze jest mniejszy zbior rekordow do sprawdzania blobka, a zatem mniej blobkow zostalo czytanych i czas mniejszy... oczywiscie jesli teksty w polu txt byly rozne (a mniemam, ze tak jest skoro napisales tylko to ze maja po kilkanascie znakow, a nie ze sa identyczne, sorki jesli zle zrozumialem zawartosc twojej tabeli ale tak mi sie zdaje)


--------------------
Go to the top of the page
+Quote Post
msulik
post 2.04.2003, 10:15:40
Post #3





Grupa: Zarejestrowani
Postów: 83
Pomógł: 0
Dołączył: 31.03.2002
Skąd: Toruń

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


Heh, to na pewno nie to. Wszystkie rekordy są takie same.

Poza tym, napisałem, że warunek na txt, to znaczy ten warunek
Kod
      tabA.txt LIKE '%a b c'

      AND

      tabA.txt LIKE '%xyz%'
jest ZAWSZE spełniony sad.gif


--------------------
misiu | chór

"Zdeterminowany programista potrafi stworzyć fatalny kod w każdym języku"
Allen Holub
Go to the top of the page
+Quote Post
dragossani
post 2.04.2003, 16:14:18
Post #4





Grupa: Przyjaciele php.pl
Postów: 398
Pomógł: 0
Dołączył: --
Skąd: Poznań

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


Zbudowałem sobie identyczną strukturę i wydałem identyczne zapytania. Oba zwróciły wyniki w ułamku sekundy. Zapuść sobie EXPLAIN przed jednym i drugim zapytaniem i porównaj wyniki. Powinny być identyczne z wyjątkiem pola EXTRA - przy pierwszym zapytaniu dochodzi 'where used'. Liczba przetwarzanych rekordów jest identyczna. Jeśli u Ciebie wygląda to inaczej to faktycznie - albo jakiś bug w Twojej wersji MySQL albo masz coś zgrzebane w konfiguracji.


--------------------
cease this long, long rest / wake and risk a foul weakness to live / when it all comes down / watch the smoke and bury the past again / sit and think what will come / raise your fears and cast them all away
Go to the top of the page
+Quote Post
msulik
post 5.04.2003, 21:38:48
Post #5





Grupa: Zarejestrowani
Postów: 83
Pomógł: 0
Dołączył: 31.03.2002
Skąd: Toruń

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


Heh, dzięki za poświęcony czas, dragossani, ale jeszcze muszę pozawracać głowę winksmiley.jpg Nadal coś mi tu nie pasi... Nie wiem, czy tak powinno być:
Zapytanie nr 1:
Kod
EXPLAIN SELECT

    COUNT(taba.tytul) AS liczba

FROM

    taba,

    tabb

WHERE

    (

  tabA.id = tabB.id

  AND

  tabA.txt LIKE '%a b c'

  AND

  tabA.txt LIKE '%xyz%'

  AND

  tabB.blobek LIKE '%ala ma kota i psa%

    )

--------------



+-------+--------+---------------+---------+---------+---------+------+------------+

| table | type   | possible_keys | key     | key_len | ref     | rows | Extra      |

+-------+--------+---------------+---------+---------+---------+------+------------+

| taba  | ALL    | PRIMARY       | NULL    |    NULL | NULL    | 1040 | where used |

| tabb  | eq_ref | PRIMARY       | PRIMARY |       4 | taba.id |    1 | where used |

+-------+--------+---------------+---------+---------+---------+------+------------+


Zapytanie nr 2:
Kod
EXPLAIN SELECT

    COUNT(taba.tytul) AS liczba

FROM

    taba,

    tabb

WHERE

    (

  tabA.id = tabB.id

  AND

  tabB.blobek LIKE '%ala ma kota i psa%'

    )

--------------



+-------+--------+---------------+---------+---------+---------+------+------------+

| table | type   | possible_keys | key     | key_len | ref     | rows | Extra      |

+-------+--------+---------------+---------+---------+---------+------+------------+

| taba  | ALL    | PRIMARY       | NULL    |    NULL | NULL    | 1040 |            |

| tabb  | eq_ref | PRIMARY       | PRIMARY |       4 | taba.id |    1 | where used |

+-------+--------+---------------+---------+---------+---------+------+------------+

Tak samo jest i u mnie na localu (wersja 3.23.56 ściągnięta dzisiaj), i na niemoim serwerze, na którym testowałem (wersja 3.23.55).

Nadal to niby łatwiejsze zapytanie wykonuje się około 11 sekund. Nie testowałem tego co prawda na tamtym serwerze, bo nie będę ładował do bazy 50 mega tylko dla testów winksmiley.jpg Może problem tkwi w czym innym? Może w definicji tabeli? Próbowałem różnych definicji i nic...

Czy u Ciebie warunki na pole txt były zawsze spełnione? :?


--------------------
misiu | chór

"Zdeterminowany programista potrafi stworzyć fatalny kod w każdym języku"
Allen Holub
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: 27.04.2024 - 20:33