Autor Zpráva
Prochy
Profil
Dobré odpoledne,

mám následující dotaz v SQL pro MySQL:
SELECT `clients`.`id`,
 UNIX_TIMESTAMP(`clients`.`date_reg`) as date_reg,
 `clients`.`surname`,
 `clients`.`first_name`,
 `sex_client`.`sex`,
 `clients`.`cell_phone`,
 `clients`.`phone`,
 `clients`.`email`,
 `categorie_client`.`categorie`,
 `source_client`.`source`,
 count(`visits`.`id`) as count_visits, 
 `clients`.`fin_debt` as fin_debt
FROM `clients` 
JOIN `categorie_client` ON (`categorie_client`.`id`=`clients`.`categorie_client`) 
JOIN`sex_client` ON (`clients`.`sex_client` = `sex_client`.`id`)
JOIN `source_client` ON(`clients`.`source_client` = `source_client`.`id`) 
LEFT JOIN `visits` ON (`clients`.`id`=`visits`.`client_id`) 
WHERE `date_reg` BETWEEN 0 AND 20120914 
GROUP BY `clients`.`id`
LIMIT 50

V tabulce clients je přes 1200 řádků a tento dotaz trvá kolem 1 sekundy a to se mi zdá poměrně dost. Počítám s tím, že nejvíce to zdržují ty JOINy, tak sem se chtěl zeptat, jak by se dal tento dotaz zrychlit. Co jsem se díval, tak nejvíce to zdrží ten count(visits), tak sem si říkal, že bych udělal v tabulce clients nový sloupec count_visits, kde bych to např. cronem každých např. 30minut aktualizoval nebo při vytvoření nového záznamu v tabulce visits danému klientu. Rád bych znal váš osobní názor.

Děkuji za případné rady.
ninja
Profil
Co říká EXPLAIN? Máte indexy nad sloupci, přes které spojujete?
Kajman
Profil
Tak visits nepřipojujte (třeba pak nebude potřeba group by). V případě limitu bude asi lepší dát poddotaz místo sloupečku v select části.
 `source_client`.`source`,
 (select count(*) from `visits` where `clients`.`id`=`visits`.`client_id`) as count_visits, 
 `clients`.`fin_debt` as fin_debt


Kromě sloupců použitých na joinech by mohl pomoci i index na date_reg. A tu podmínku bych zkusil napsat jako
WHERE `clients`.`date_reg` <= '2012-09-14'
ale to možná nic neovlivní
Tori
Profil
Prochy:
Jen dotaz ze zvědavosti: proč máte rod klientů jako samostatnou tabulku - kvůli pozdějšímu rozšíření o překlady? Nestačil by třeba sloupeček ENUM('F', 'M', 'other', '') a případně to překládat v šabloně?
Prochy
Profil
Tak se omlouvám, za obtěžování. Problém byl v tom, že sem zapoměl dát index na sloupec visits.client_id, takže to procházelo všechno. Po indexaci dotaz netrvá ani 15ms. Přišel jsem na to po příkazu EXPLAIN. Nevěděl sem pořádně, jak se ten EXPLAIN používá a co který sloupec znamená. Takže děkuji za případné rady.

Tori:
Vím, je to zbytečné ani nevim proč jsem to udělal, když sem databázi navrhoval. Ale jelikož to databázi zdržuje minimálně, tak už sem to nechtěl měnit.

Takže ještě jednou díky.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: