![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 124 Pomógł: 1 Dołączył: 13.07.2009 Ostrzeżenie: (0%) ![]() ![]() |
Mam takie zapytanie:
Służy do wylistowania / wyszukania artykułów dla danej kategorii. Dodatkowo zwraca mi dodatkowe informacje o dodającym oraz o osobie, która jako ostatnia edytowała artykuł (edytować może autor lub administrator), m.in to czy dodający lub ostatni edytujący jest administratorem, czy też zwykłym użytkownikiem. Oczywiście zamiast tego zera przy limicie pojawia się odpowiedni offset ![]() Dla testu dodałem ok. 1000 artykułów do bazy. Niestety zapytanie zbyt długo się wykonuje, a i tak testuję to tylko na localhoście. Czas więc zoptymalizować składnię zapytania o ile się da no i dodać indeksy. Tabela artykułów:
Pole member_username w tabeli members:
I pytanie tak na marginesie - stosować słówko AS w zapytaniach czy lepiej skrócony zapis bez tego słowa kluczowego? |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 702 Pomógł: 65 Dołączył: 16.03.2009 Ostrzeżenie: (0%) ![]() ![]() |
skoro wyszukujesz po
to czemu tutaj klucza nie zastosowałeś ? -------------------- Nie udzielam pomocy poprzez PW
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 855 Pomógł: 145 Dołączył: 17.07.2008 Skąd: High Memory Area Ostrzeżenie: (0%) ![]() ![]() |
Podzapytania w liście pól wykonują się dla każdego wiersza tabeli 'articles'. Pora zapoznać się ze złączeniami.
Kod <pre> SELECT
SQL_CALC_FOUND_ROWS a.article_id, a.article_status, a.article_views, a.article_date_added, a.article_date_modified, a.article_desc, a.article_adder, a.article_last_changer, a.article_name, ad.member_level as `adder_level`, alc.member.level as `last_changer_level` FROM articles as `a` INNER JOIN members AS ad ON LOWER(ad.member_username)=LOWER(a.article_adder) INNER JOIN members AS alc ON LOWER(alc.member_username)=LOWER(a.article_last_changer) WHERE a.article_category_id=1 -- tu odpowiednie Id ORDER BY a.article_date_added DESC LIMIT 0,20; Ten post edytował Mchl 20.02.2010, 17:18:26 |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 124 Pomógł: 1 Dołączył: 13.07.2009 Ostrzeżenie: (0%) ![]() ![]() |
Ok dzięki Mchl.
Złączenia już wykorzystywałem kilka razy, jednak w tym wypadku nie udawało mi się uzyskać pożądanych efektów więc tymczasowo zastosowałem podzapytania. Co prawda musiałem zmienić w Twoim zapytaniu INNER JOIN-y na LEFT JOIN-y bo nie dostawałem wyników, ale teraz już jest OK. Tak w ogóle to masz literówkę w: Cytat alc.member.level Cytat("gothye") skoro wyszukujesz po
to czemu tutaj klucza nie zastosowałeś ? Bo kategorii będzie bardzo niewiele, na początku ok. 15, maksymalnie myślę, że około 30. Mam jeszcze jeden mały problem. W menu mam wylistowane kategorie i chcę by obok każdej w nawiasie pokazało ile przypada widocznych artykułów dla danej kategorii. O tym czy artykuł jest widoczny decyduje jego status z zakresu od 0 do 6. Widoczne są tylko te ze statusem od 0 do 2 lub ze statusem 6. Kategorie też mają swoje statusy, ale tylko od 0 do 3 i widoczne są wszystkie ze statusem mniejszym niż 3. Tabela kategorii:
Na razie najlepsze zapytanie jakie udało mi się wymyślić ma taką postać:
Dla ok. 1000 artykułów zapytanie wykonuje się średnio w 0.45 s, czyli chyba za długo. Indeksów chyba nie ma sensu zakładać na pola id i status prawda? Jak sami widzicie zapytanie mocno kombinowane :/ Zapytanie musi mi zwrócić również kategorie nieposiadające artykułów (0 w nawiasie). Ten post edytował Walian 20.02.2010, 22:32:54 |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 855 Pomógł: 145 Dołączył: 17.07.2008 Skąd: High Memory Area Ostrzeżenie: (0%) ![]() ![]() |
Bo kategorii będzie bardzo niewiele, na początku ok. 15, maksymalnie myślę, że około 30. No to co? Ważne po ile będzie artykułów w każdej kategorii. Spróbuj tak: Kod SELECT
ac.category_id, ac.category_status, ac.category_name, ac.category_title, a.articles_count FROM articles_categories AS `ac` LEFT JOIN ( SELECT article_category_id COUNT(*) AS articles_count FROM articles AS `a` WHERE (a.article_status < 3) OR (a.article_status = 6) GROUP BY article_category_id ) AS a ON (a.article_category_id=ac.category_id) WHERE (ac.category_status < 3) Ten post edytował Mchl 20.02.2010, 22:48:14 |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 124 Pomógł: 1 Dołączył: 13.07.2009 Ostrzeżenie: (0%) ![]() ![]() |
0.13 s
![]() Dzięki wielkie. |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 855 Pomógł: 145 Dołączył: 17.07.2008 Skąd: High Memory Area Ostrzeżenie: (0%) ![]() ![]() |
Możesz spróbować jeszcze z indeksem na:
ALTER TABLE articles_categories ADD INDEX category_id_category_status(category_id,category_status) albo odwrotnie... nigdy nie jestem pewien w którą stronę MySQL sobie ułoży kolumny ![]() |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 124 Pomógł: 1 Dołączył: 13.07.2009 Ostrzeżenie: (0%) ![]() ![]() |
Mam jeszcze jeden problem, to zapytanie które służy do pobrania artykułów danego użytkownika ("Moje artykuły"):
Wynik: ![]() Tabela ma łącznie 2247 artykułów czyli o 2 więcej niż ma testowy użytkownik. Zapytanie bez explain wykonuje się w ok. 0.36 s. Jak widać explain zwrócił "rows" o wartości 2245 - czy tak powinno być skoro ja wybieram tylko 20 artykułów? Zapytanie jest dobrze ułożone? |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 855 Pomógł: 145 Dołączył: 17.07.2008 Skąd: High Memory Area Ostrzeżenie: (0%) ![]() ![]() |
SQL_CALC_FOUND_ROWS wymusza wykonanie zapytania bez LIMIT (w uproszczeniu), po to aby policzyć właśnie wszystkie wiersze spełniające dany warunek.
|
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 124 Pomógł: 1 Dołączył: 13.07.2009 Ostrzeżenie: (0%) ![]() ![]() |
A bez uproszczenia
![]() 1. Wykonanie zapytań z EXPLAIN zarówno z SQL_CALC_FOUND_ROWS jak i bez niego - zwraca ten sam wynik. 2. Wykonanie obu zapytań bez EXPLAIN skutkuje tym, że to bez SQL_CALC_FOUND_ROWS jest prawie dwukrotnie szybsze. |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 855 Pomógł: 145 Dołączył: 17.07.2008 Skąd: High Memory Area Ostrzeżenie: (0%) ![]() ![]() |
Generalnie zaufał bymw tym wypadku ludziom z Percony:
http://www.mysqlperformanceblog.com/2007/0...alc_found_rows/ |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 31.07.2025 - 10:42 |