Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Powolne przeglądanie produktów
Walian
post
Post #1





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


Witam,

Pracuję nad pewnym serwisem internetowym (niestety nie wolno mi podawać nazwy ani adresu), który zaczyna już dość mocno zwalniać. W chwili obecnej problem stanowią dwie tabele:
- tabela produktów - MyISAM, ponad 700 tyś rekordów, ponad 180 MB.
- tabela ofert do produktów - MyISAM, ponad 1 125 000 rekordów, ponad 230 MB.

Do rzeczy - problem stanowi już samo przeglądanie produktów.
  1. SELECT
  2. SQL_NO_CACHE
  3. SQL_CALC_FOUND_ROWS
  4. `p`.`produkt_id`,
  5. `p`.`name`,
  6. `p`.`katalog`,
  7. `p`.`pod_katalog`,
  8. `p`.`category_id`,
  9. `o`.`user_id`,
  10. `o`.`cena`,
  11. `o`.`id` AS `id_offer`
  12. FROM
  13. `produkty` `p`
  14. INNER JOIN
  15. `oferty` `o`
  16. ON
  17. `o`.`produkt_id`=`p`.`produkt_id`
  18. LEFT JOIN
  19. `uzytkownicy` `u`
  20. ON
  21. `u`.`user_id`=`o`.`user_id`
  22. WHERE
  23. `u`.`aktywny`=1 ; Tu waskie gardlo...
  24. ; W chwili obecnej wszyscy maja "1", ale TO sie kiedys zmieni...
  25. AND
  26. `p`.`category_id` IN (tutaj 176 numerow (cale drzewko) kategorii)
  27. AND ; Od tego momentu rozne filtry:
  28. `o`.`cena` BETWEEN 1 AND 99999
  29. ORDER BY
  30. `p`.`name` ASC ; Zamiast tego moze sie pojawic sortowanie wg ceny
  31. LIMIT 0,20

Cytat
20 rows in set (9.70 sec)

Bez SQL_CALC_FOUND_ROWS:
Cytat
20 rows in set (6.63 sec)

To samo zapytanie, ale bez wyciągania danych - zamiast tego COUNT(*):
Cytat
20 rows in set (6.71 sec)

Teraz wracając do początku:
Bez "`u`.`aktywny`=1":
Cytat
20 rows in set (1.86 sec)

Bez "`u`.`aktywny`=1" oraz bez "ORDER BY `p`.`name` ASC":
Cytat
20 rows in set (1.16 sec)

Bez "`u`.`aktywny`=1" oraz bez "`o`.`cena` BETWEEN 1 AND 99999" oraz bez "ORDER BY `p`.`name` ASC":
Cytat
20 rows in set (1.07 sec)

Ostatnie zapytanie, ale bez SQL_CALC_FOUND_ROWS:
Cytat
20 rows in set (0.00 sec)


Serwis stoi na serwerze dedykowanym...

Jak przyspieszyć to zapytanie? Nie mogę zrezygnować z tych warunków WHERE, ale może da radę jakoś inaczej zapytanie skonstruować?
Przejście na InnoDB pomoże czy rozwiązania trzeba szukać gdzie indziej?
Go to the top of the page
+Quote Post
erix
post
Post #2





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




A nie możesz po prostu wywołać dwóch zapytań? Jedno count z tymi warunkami, drugie właściwe? Myślę, że szybciej będzie.


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

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
nospor
post
Post #3





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




zrob z tego zapytania EXPLAIN i zobacz na czym muli.
Zapewne musisz pozakładać własciwe indexy


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

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Walian
post
Post #4





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


Cytat("erix")
A nie możesz po prostu wywołać dwóch zapytań? Jedno count z tymi warunkami, drugie właściwe? Myślę, że szybciej będzie.

Cytat("Walian")
To samo zapytanie, ale bez wyciągania danych - zamiast tego COUNT(*):
Cytat
20 rows in set (6.71 sec)

Jak widzisz jest jeszcze gorzej, już bardziej się opłaca z SQL_CALC_FOUND_ROWS.

EXPLAIN EXTENDED:
Cytat
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE u ALL PRIMARY NULL NULL NULL 892 Using where; Using temporary; Using filesort
1 SIMPLE o ref produkt_id,user_id,cena user_id 3 u.user_id 19 Using where
1 SIMPLE a eq_ref PRIMARY,category_id PRIMARY 4 o.produkt_id 1 Using where

Próbowałem już wcześniej z różnymi indeksami, z pozbywaniem się filesort-a, nawet z FORCE INDEX, no ale nie wiem jak sobie z tym poradzić.
Go to the top of the page
+Quote Post
erix
post
Post #5





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Huh, nie zauważyłem...

Pokaż lepiej
  1. SHOW CREATE TABLE


A jeśli chodzi o rozwiązanie - musisz każdorazowo odpytywać DB? Nie myślałeś o cache po stronie klienta? (nie mylić z cache demona)


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

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
Walian
post
Post #6





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


Ale jak niby taki cache zrobić? Nie widzę tu sensu, skoro najmniejsza zmiana w filtrze, przejście do innej kategorii, czy wyszukiwanie wg jakieś frazy zmienia już postać i ilość wyników. Po stronie serwera też nie ma sensu bo powstanie olbrzymia ilość plików cache. Jeśli do tego uwzględnić fakt, że ciągle są dodawane lub aktualizowane produkty to liczba "kombinacji" jest olbrzymia.

  1. SHOW CREATE TABLE `uzytkownicy`;
  2. CREATE TABLE `uzytkownicy` (
  3. `user_id` int(11) NOT NULL AUTO_INCREMENT,
  4. `aktywny` int(11) NOT NULL DEFAULT '1',
  5. PRIMARY KEY (`user_id`),
  6. FULLTEXT KEY `nazwa_sklepu` (`nazwa_sklepu`),
  7. FULLTEXT KEY `city` (`city`)
  8. ) ENGINE=MyISAM AUTO_INCREMENT=100962 DEFAULT CHARSET=latin2 PACK_KEYS=0
  9. -- Indeks na polu "aktywny" nic nie daje, bo w kazdym rekordzie jest "1", przynajmniej na razie
  10.  
  11. SHOW CREATE TABLE `produkty`;
  12. CREATE TABLE `produkty` (
  13. `produkt_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  14. `name` varchar(255) NOT NULL,
  15. `category_id` smallint(11) NOT NULL DEFAULT '0',
  16. `katalog` tinyint(4) NOT NULL DEFAULT '0',
  17. `pod_katalog` tinyint(4) NOT NULL DEFAULT '0',
  18. PRIMARY KEY (`produkt_id`),
  19. KEY `products_name` (`active`,`name`),
  20. KEY `category_id` (`category_id`),
  21. FULLTEXT KEY `name` (`name`)
  22. ) ENGINE=MyISAM AUTO_INCREMENT=911612 DEFAULT CHARSET=utf8 PACK_KEYS=0
  23.  
  24. SHOW CREATE TABLE `oferty`;
  25. CREATE TABLE `oferty` (
  26. `id` int(11) NOT NULL AUTO_INCREMENT,
  27. `user_id` mediumint(10) NOT NULL DEFAULT '0',
  28. `cena` double(16,2) NOT NULL DEFAULT '0.00',
  29. `nazwa_prod` varchar(255) NOT NULL,
  30. `offer_id` bigint(24) UNSIGNED NOT NULL,
  31. `produkt_id` int(10) UNSIGNED NOT NULL,
  32. PRIMARY KEY (`id`),
  33. KEY `produkt_id` (`produkt_id`),
  34. KEY `user_id` (`user_id`),
  35. KEY `cena` (`cena`)
  36. ) ENGINE=MyISAM AUTO_INCREMENT=1357689 DEFAULT CHARSET=utf8


Wyciąłem kolumny, które nie biorą udziału w zapytaniu. Zresztą jest ich od cholery...
Wiem, wiem - tragedia... ale muszę to jakoś przyspieszyć ;/
Go to the top of the page
+Quote Post
erix
post
Post #7





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Wyciąłem kolumny, które nie biorą udziału w zapytaniu. Zresztą jest ich od cholery...

Hmm, a nie myślałeś o rozbiciu tego na wiele tabel? Np. opisy w osobnej, łączone relacją 1-1.

Jeśli są kolumny typu text/varchar - przyspieszy to wyszukiwanie.


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

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
wookieb
post
Post #8





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Daj całe create table (nie usuwaj "zbędnych" kolumn) bo nie mam jak tego przetestować na bazie aby w troszkę mniejszym stopniu pobawić się z optymalizacją.

Cytat
Jeśli są kolumny typu text/varchar - przyspieszy to wyszukiwanie.

Nie ma to żadnego znaczenia w tym zapytaniu


--------------------
Go to the top of the page
+Quote Post
Walian
post
Post #9





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


Gdybym projektował ten serwis od początku to tak właśnie bym zrobił bo upraszcza to również eksport danej tabeli, czy jej przywracanie.
W sumie najwięcej kolumn (39, większość to VARCHAR) jest w tabeli userów, tabele produktów i ofert akurat nie mają ich dużo.
Niestety musiałbym napisać skrypt, który to wszystko rozdzieli, a potem zatrzymać serwis na czas wszystkich operacji. A nie chcę robić tego wszystkiego jeśli nie mam gwarancji, że to da cokolwiek. Tym bardziej, że dopiero przenieśliśmy się na dedyka, co zajęło masę czasu.

Myślisz, że na pewno się opłaci? W sumie i tak musiałbym poczekać z tym do poniedziałku, aż wróci drugi programista. Do tego czasu szukam różnych, alternatywnych rozwiązań.

EDIT: To wyżej było do erixa, spóźniłem się z postem smile.gif
wookieb - zaraz zapodam.

Ten post edytował Walian 17.08.2010, 12:09:15
Go to the top of the page
+Quote Post
kaminskp
post
Post #10





Grupa: Zarejestrowani
Postów: 98
Pomógł: 0
Dołączył: 18.03.2008
Skąd: Olsztyn

Ostrzeżenie: (20%)
X----


Sugeruję zastosowanie AJAX on szybko dłubie w danych i zwraca wyniki.
Go to the top of the page
+Quote Post
erix
post
Post #11





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Nie ma to żadnego znaczenia w tym zapytaniu

Czy ja wiem? Jeśli są kolumny różnej długości, to nie ma możliwości odczytu sekwencyjnego (paczkami o stałej długości), tylko trzeba każdorazowo tę długość sprawdzać i wtedy skakać...

~kaminskp - tiaa, tylko że w poruszanym problemie nie ma jak wykonać jakiegokolwiek JS...


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

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
Walian
post
Post #12





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


  1. CREATE TABLE `produkty` (
  2. `produkt_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `name` varchar(255) NOT NULL,
  4. `category_id` smallint(11) NOT NULL DEFAULT '0',
  5. `active` tinyint(4) NOT NULL DEFAULT '0',
  6. `poprawiony` tinyint(4) NOT NULL DEFAULT '0',
  7. `katalog` tinyint(4) NOT NULL DEFAULT '0',
  8. `pod_katalog` tinyint(4) NOT NULL DEFAULT '0',
  9. PRIMARY KEY (`produkt_id`),
  10. KEY `products_name` (`active`,`name`),
  11. KEY `category_id` (`category_id`),
  12. FULLTEXT KEY `name` (`name`)
  13. ) ENGINE=MyISAM AUTO_INCREMENT=913300 DEFAULT CHARSET=utf8 PACK_KEYS=0


  1. CREATE TABLE `oferty` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `user_id` mediumint(10) NOT NULL DEFAULT '0',
  4. `cena` double(16,2) NOT NULL DEFAULT '0.00',
  5. `nazwa_prod` varchar(255) NOT NULL,
  6. `link` varchar(255) NOT NULL,
  7. `offer_id` bigint(24) UNSIGNED NOT NULL,
  8. `produkt_id` int(10) UNSIGNED NOT NULL,
  9. `aktualizacja` int(8) NOT NULL,
  10. PRIMARY KEY (`id`),
  11. KEY `produkt_id` (`produkt_id`),
  12. KEY `user_id` (`user_id`),
  13. KEY `cena` (`cena`)
  14. ) ENGINE=MyISAM AUTO_INCREMENT=1359539 DEFAULT CHARSET=utf8


A teraz czas na MATRIX:
  1. CREATE TABLE `uzytkownicy` (
  2. `user_id` int(11) NOT NULL AUTO_INCREMENT,
  3. `name` varchar(100) character SET utf8 NOT NULL,
  4. `email` varchar(255) character SET utf8 NOT NULL,
  5. `birthdate` date NOT NULL DEFAULT '0000-00-00',
  6. `address` varchar(100) character SET utf8 NOT NULL,
  7. `city` varchar(50) character SET utf8 collate utf8_polish_ci NOT NULL,
  8. `state` varchar(100) character SET utf8 NOT NULL,
  9. `country` varchar(100) character SET utf8 NOT NULL,
  10. `zip_code` varchar(30) NOT NULL DEFAULT '',
  11. `phone` varchar(30) NOT NULL DEFAULT '',
  12. `username` varchar(255) NOT NULL DEFAULT '',
  13. `password` varchar(32) NOT NULL DEFAULT '',
  14. `active` tinyint(4) NOT NULL DEFAULT '0',
  15. `zdjecie_logo` varchar(255) NOT NULL,
  16. `xml_link` varchar(225) NOT NULL,
  17. `xml_nazwa` varchar(50) NOT NULL,
  18. `pp` int(3) NOT NULL DEFAULT '0',
  19. `opis_problem` varchar(255) character SET utf8 NOT NULL,
  20. `payment_status` varchar(20) NOT NULL DEFAULT '',
  21. `automat` int(11) NOT NULL DEFAULT '0',
  22. `poprawny_plik` int(3) NOT NULL DEFAULT '0',
  23. `newsletter` tinyint(4) NOT NULL DEFAULT '0',
  24. `reg_date` int(11) NOT NULL DEFAULT '0',
  25. `mail_activated` tinyint(4) NOT NULL DEFAULT '0',
  26. `lang` varchar(255) NOT NULL DEFAULT 'english',
  27. `preferred_seller` tinyint(4) NOT NULL DEFAULT '0',
  28. `promowanie_sklepu` tinyint(4) NOT NULL DEFAULT '0',
  29. `birthdate_year` int(11) NOT NULL DEFAULT '0',
  30. `referred_by` varchar(200) NOT NULL DEFAULT '',
  31. `payment_mode` tinyint(1) DEFAULT '0',
  32. `ilosc_prod` int(11) DEFAULT '0',
  33. `nazwa_sklepu` varchar(100) character SET utf8 DEFAULT NULL,
  34. `tax_account_type` tinyint(4) NOT NULL DEFAULT '0',
  35. `salt` char(3) NOT NULL DEFAULT '',
  36. `approved` tinyint(4) NOT NULL DEFAULT '0',
  37. `aktualizacja` text NOT NULL,
  38. `prom_logo` int(3) NOT NULL DEFAULT '0',
  39. `akceptacja_promowanie` int(2) NOT NULL,
  40. `aktywny` int(11) NOT NULL DEFAULT '1',
  41. PRIMARY KEY (`user_id`),
  42. KEY `shop_active` (`active`,`user_id`),
  43. KEY `stores_list` (`active`),
  44. KEY `acc_overdue_users` (`payment_mode`,`reg_date`),
  45. KEY `active_users` (`active`,`reg_date`,`approved`),
  46. KEY `users_tax_acc_type` (`tax_account_type`,`reg_date`),
  47. KEY `users_tax_exempt` (`promowanie_sklepu`,`reg_date`),
  48. KEY `active` (`active`),
  49. FULLTEXT KEY `nazwa_sklepu` (`nazwa_sklepu`),
  50. FULLTEXT KEY `city` (`city`)
  51. ) ENGINE=MyISAM AUTO_INCREMENT=100962 DEFAULT CHARSET=latin2 PACK_KEYS=0


Pewnie kilka kolumn nie jest w ogóle używanych, to się je prędzej czy później wywali.
Go to the top of the page
+Quote Post
wookieb
post
Post #13





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(kaminskp @ 17.08.2010, 13:11:49 ) *
Sugeruję zastosowanie AJAX on szybko dłubie w danych i zwraca wyniki.

Idź do kąta, zastanów się nad swoim postępowaniem i nie gadaj głupot.


--------------------
Go to the top of the page
+Quote Post
erix
post
Post #14





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Na próbę - przenieś kolumny varchar/text (tyle, ile się da) do osobnej tabeli, np. userMeta zostawiając pozostałe. Oczywiście nazwa użytkownika i login trzeba zostawić.

I teraz zobacz, ile czasu zajmie wyciągnięcie z tej pierwszej, z atrybutem aktywny=1. Podejrzewam, że przyspieszy. Wtedy JOIN z drugą tabelą (relacja 1-1 po np. ID użytkownika) i pokaż, jak wychodzi czas.

Nie siedzę aż tak mocno w bazach, więc moje myślenie może być błędne (niech kto poprawi, jeśli tak jest), ale patrząc na logikę działania wydaje mi się całkiem sensowne.

Najlepiej niech zweryfikują to fakty. winksmiley.jpg


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

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
wookieb
post
Post #15





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Niestety MyIsam słabo spisuje się w operacjach złączenia (wynika to między innymi z tego powodu, że nie przechowuje głównego indeksu tabeli w kluczach tak jak INNODB).
Po próbie zmiany myisam na innodb złączenia odrazu zaczęły wykorzystywać klucze.
Próbuję "conieco" zoptymalizować tabele i wynikami pochwale się jak tylko uda mi się coś zrobić aczkolwiek zastanów się na przyszłość czy nie lepiej przejśc na INNODB i do wyszukiwania wykorzystać sphinxa bądź inne systemy wyszukiwania (w zastępstwie FULLTEXT).

Ten post edytował wookieb 17.08.2010, 12:40:00


--------------------
Go to the top of the page
+Quote Post
Walian
post
Post #16





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


Stworzyłem nawet nieco mniejszą tabelkę dla testu:
  1. CREATE TABLE `uzytkownicy2` (
  2. `user_id` int(11) NOT NULL AUTO_INCREMENT,
  3. `state` varchar(100) character SET utf8 NOT NULL,
  4. `nazwa_sklepu` varchar(100) character SET utf8 DEFAULT NULL,
  5. `aktywny` int(11) NOT NULL DEFAULT '1',
  6. PRIMARY KEY (`user_id`),
  7. FULLTEXT KEY `nazwa_sklepu` (`nazwa_sklepu`)
  8. ) ENGINE=MyISAM AUTO_INCREMENT=100962 DEFAULT CHARSET=latin2 PACK_KEYS=0

Niestety ZERO przyspieszenia. A nawet działa nieco wolniej, choć to może być przypadek.

wookieb - ja zawsze byłem za InnoDB, ale jak wspominałem - nie ja zacząłem projektować ten serwis. Co do Sphinxa - nigdy z niego nie korzystałem, tak więc nie znam się na nim, wyczytałem jedynie mnóstwo pozytywnych opinii na jego temat, także kiedyś na pewno się nim pobawię, ale chyba nie w tym serwisie, bo raczej nie będzie na to czasu.

Ten post edytował Walian 17.08.2010, 12:45:27
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #17





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

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


Hmm, indeksy na kolumnach zlaczen są.

Robisz LEFT JOINA do userów, a potem WHERE user.is_active = 1.
Czyli wlasciwie LEFT JOIN ci nie potrzebny - bo jesli nie znajdize usera to kolumny 'userowe' beda mialy wszedzie NULLe a NULL =?= true zawsze jest NIEspelnione.

Po tej zmianie EXPLAIN dla tabeli userow uzywa u mnie klucza glownego zamiast robic full scan'a.
-----
Przed
Kod
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE u ALL PRIMARY NULL NULL NULL 892 Using where; Using temporary; Using filesort
1 SIMPLE o ref produkt_id,user_id,cena user_id 3 u.user_id 19 Using where
1 SIMPLE a eq_ref PRIMARY,category_id PRIMARY 4 o.produkt_id 1 Using where
// produkty ma alias 'a' questionmark.gif?

Kod
id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra    
1    SIMPLE    u    index    PRIMARY    PRIMARY    4    NULL    12    Using index; Using temporary; Using filesort
1    SIMPLE    o    ref    produkt_id,user_id,cena    user_id    3    test.u.user_id    15    Using where
1    SIMPLE    p    eq_ref    PRIMARY,category_id    PRIMARY    4    test.o.produkt_id    1    Using where



jako że danych mam neiwiele (180 ofert) to czasów nie jestem w stanie podać.

Ten post edytował dr_bonzo 17.08.2010, 13:13:15


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Walian
post
Post #18





Grupa: Zarejestrowani
Postów: 124
Pomógł: 1
Dołączył: 13.07.2009

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


Nie kumam - jeśli nie LEFT JOIN to co?
Cytat
bo jesli nie znajdize usera to kolumny 'userowe' beda mialy wszedzie NULLe a NULL =?= true zawsze jest NIEspelnione.

Sprawdziłem tak:
  1. SELECT SQL_NO_CACHE COUNT(*) FROM
  2. (
  3. SELECT SQL_NO_CACHE `p`.`produkt_id`,`p`.`name`,`p`.`katalog`,`p`.`pod_katalog`,`p`.`category_id`,`o`.`user_id`,`o`.`cena`,`o`.`id` AS id_offer,`u`.`aktywny` FROM `produkty` `p` INNER JOIN `oferty` `o` ON `o`.`auction_id`=`p`.`auction_id` LEFT JOIN `uzytkownicy` `u` ON `u`.`user_id`=`o`.`user_id` WHERE `u`.`aktywny`=1 AND `p`.`category_id` IN (numerki) AND `o`.`cena` BETWEEN 1 AND 99999 ORDER BY `p`.`name` ASC LIMIT 0,20
  4. ) AS `r`
  5. WHERE
  6. aktywny = NULL;

Zwróciło 0.
Chyba, że źle zrozumiałem lub źle sprawdziłem.

Nie wiem, co żeś za zapytanie zmajstrował, że Ci takie EXPLAIN wyszło.
Go to the top of the page
+Quote Post
VegetaSSJ
post
Post #19





Grupa: Zarejestrowani
Postów: 78
Pomógł: 2
Dołączył: 21.10.2006

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


a wiedziałeś o tym że:

  1. `p`.`category_id` IN (tutaj 176 numerow (cale drzewko) kategorii)


rozbijane jest na:

  1. AND (`p`.`category_id` = nr1 OR `p`.`category_id` = nr2 OR `p`.`category_id` = nr3 OR ... `p`.`category_id` = nr176)


jeżeli masz drzewko kategorii oparte na left-right lepiej będzie zastąpić to beetwenem z podaniem odpwiednich wartści roota drzewka.

Ten post edytował VegetaSSJ 17.08.2010, 14:33:07
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #20





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

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


Cytat
Nie kumam - jeśli nie LEFT JOIN to co?

To INNER JOIN (zapomnialem dopisac)

i

Cytat
...WHERE
aktywny = NULL;


o czyms zapomniales:
  1. SELECT NULL = NULL, 1 = NULL, 0 = NULL, 0 = 1, 0 = 0


---
no i SQLka szukajaca

  1. SELECT
  2. SQL_NO_CACHE SQL_CALC_FOUND_ROWS `p`.`produkt_id`, `p`.`name`, `p`.`katalog`, `p`.`pod_katalog`, `p`.`category_id`, `o`.`user_id`, `o`.`cena`, `o`.`id` AS `id_offer`, u.user_id
  3. FROM `produkty` `p`
  4. INNER JOIN `oferty` `o` ON `o`.`produkt_id`=`p`.`produkt_id`
  5. INNER JOIN `uzytkownicy` `u` ON `u`.`user_id`=`o`.`user_id`
  6. WHERE
  7. -- `u`.`aktywny`=1 AND
  8. `p`.`category_id` IN (2, 23, 32, 35, 48, 49, 52, 65, 66, 77, 79, 89, 98) AND -- 180 IDekow kategorii
  9. `o`.`cena` BETWEEN 1 AND 99999
  10. ORDER BY
  11. `p`.`name` ASC

LIMIT 0,20

Ten post edytował dr_bonzo 17.08.2010, 14:39:16


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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 Aktualny czas: 22.08.2025 - 09:17