Cześć,
mam takie zapytanie:
SELECT a.*,IF (a.date_end = '0000-00-00', 9999998, IF (TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) < 0, 9999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ))) toend, count(b.articles_id) udzial FROM articles a LEFT JOIN articles_brkon b ON (b.typ=1 AND a.id=b.articles_id) WHERE (TO_DAYS( curdate( ) ) -TO_DAYS( a.date_end )>=120) AND cid IN (2,4) AND a.st=1 GROUP BY a.id ORDER BY IF (a.date_end = '0000-00-00', 999998,IF (TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) < 0, 999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ))) LIMIT 39370, 10;
SELECT * FROM articles WHERE (TO_DAYS( curdate( ) ) -TO_DAYS( date_end )>=120) AND cid IN (2,4) AND st=1
SELECT * FROM articles
SELECT * FROM articles_brkon
SELECT * FROM articles_brkon WHERE typ=1
SELECT a.*,IF (a.date_end = '0000-00-00', 9999998, IF (TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) < 0, 9999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ))) toend FROM articles a WHERE (TO_DAYS( curdate( ) ) -TO_DAYS( a.date_end )>=120) AND cid IN (2,4) AND a.st=1 ORDER BY IF (a.date_end = '0000-00-00', 999998,IF (TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) < 0, 999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ))) LIMIT 39370, 10;
SELECT articles_id, count(*) FROM articles_brkon WHERE typ=1 AND articles_id IN ({rekordy}) GROUP BY articles_id
ORDER BY IF (a.date_end = '0000-00-00', 999998,IF (TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) < 0, 999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) )))
ORDER BY CASE `date_end` WHEN a.date_end = '0000-00-00' THEN 999998 WHEN TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) <0 THEN 999999 ELSE TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) END ASC
1)formatuj zapytania. Użycie entera naprawdę nie boli, a czytelność poprawia znacząco
2)pokaz wynik EXPLAIN
A po co ci LEFT JOIN ? On psuje...
EXPLAIN SELECT a . * , IF( a.date_end = '0000-00-00', 9999998, IF( TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) <0, 9999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) ) ) toend, count( b.articles_id ) udzial FROM articles a LEFT JOIN articles_brkon b ON ( b.typ =1 AND a.id = b.articles_id ) WHERE ( TO_DAYS( curdate( ) ) - TO_DAYS( a.date_end ) >=120 ) AND cid IN ( 2, 4 ) AND a.st =1 GROUP BY a.id ORDER BY IF( a.date_end = '0000-00-00', 999998, IF( TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) <0, 999999, TO_DAYS( a.date_end ) - TO_DAYS( curdate( ) ) ) ) LIMIT 39370 , 10
spróbuj dać indeks na a.st lub wspólny na cid i a.st jeśli to ta sama tabela
możesz też spróbować zamienić kolejnością warunki
a.st and cid TO_DAYS
ile rekordów jest faktycznie wyświetlanych ? to znaczy ile spełnia warunki jeśli pominie się limit
Do wyświetlenia jest 48,511 rekordów...
jeśli pominę count to zapytanie trwa ułamki sekundy, ale wtedy wyświetla 827033 rekordów, gdy dam SELECT DISTINCT bez count to zapytanie trwa ok 1.5s no ale nie zlicza ile osób przeczytało artykuł...
Rozbiłem to na dwa zapytania pobieram wszystkie informacje poza count, pętlą pobieram same articles_id i robię
SELECT articles_id, count(*) udzial FROM articles_brkon WHERE articles_id IN ({$id}) AND typ =1 GROUP BY articles_id
a gdyby przenieść tego counta do podzapytania ?
EXPLAIN SELECT count(*) total FROM forum_posts p WHERE p.post_deleted=0 AND p.post_message LIKE '%ABC%'
Czemu nie chce dać indeksu?
Bo masz LIKE. Zastosuj funkcje do FULLTEXTa, to użyje..
Jeżeli być miał LIKE 'ABC%' to by zadziałał, ale tak jak @mmmmmmm napisał użyj funkcji która używa fulltext index
Dałem:
SELECT count(*) total FROM forum_posts p WHERE p.post_deleted=0 AND MATCH (p.post_message) AGAINST ('abc' IN BOOLEAN MODE) // wynik 0 SELECT count(*) total FROM forum_posts p WHERE p.post_deleted=0 AND MATCH (p.post_message) AGAINST ('*abc*' IN BOOLEAN MODE) // wynik 136 SELECT count(*) total FROM forum_posts p WHERE p.post_deleted=0 AND MATCH (p.post_message) AGAINST ('abc') // wynik 0 SELECT count(*) total FROM forum_posts p WHERE p.post_deleted=0 AND MATCH (p.post_message) AGAINST ('*abc*') // wynik 0 SELECT count(*) total FROM forum_posts p WHERE p.post_deleted=0 AND p.post_message LIKE '%abc%' // wynik 11255
SELECT a.* , ( SELECT count(*) FROM articles_brkon b WHERE b.typ =1 AND a.id = b.articles_id ) AS udzial FROM articles a
MATCH (p.post_message) AGAINST ('+abc*' IN BOOLEAN MODE)
SELECT a.* , ( SELECT count(*) FROM articles_brkon b WHERE b.typ =1 AND a.id = b.articles_id ) AS udzial FROM articles a
MATCH (p.post_message) AGAINST ('+abc*' IN BOOLEAN MODE)
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)