2012-09-13 4 views
1

La requête ci-dessous même sans le order by est très lent et je ne peux pas comprendre pourquoi. Je suppose que c'est le where date_affidavit_file mais comment puis-je le faire rapidement avec ce order by aussi bien? Peut-être un sous-job sur le job_id qui correspond à l'endroit et ensuite passer dans le reste du code mais j'ai toujours besoin de commander par serveur le nom du serveur comme ceci. Aucune suggestion?mysql lente requête complexe avec l'ordre par

explain select sql_no_cache court_county, job.id as jid, job_status, 
    DATE_FORMAT(job.datetime_served, '%m/%d/%Y') as dserved , 
    CONCAT(server.namefirst, ' ', server.namelast) as servername, client_name, 
    DATE_FORMAT(job.datetime_received, '%m/%d/%Y') as dtrec , 
    DATE_FORMAT(job.datetime_give2server, '%m/%d/%Y') as dtg2s, 
    DATE_FORMAT(date_kase_filed, '%m/%d/%Y') as dkf, 
    DATE_FORMAT(job.date_sent_to_court, '%m/%d/%Y') as dtstc , 
    TO_DAYS(datetime_served)-TO_DAYS(date_kase_filed) as totaldays from job 
    left join kase on kase.id=job.kase_id 
    left join server on job.server_id=server.id 
    left join client on kase.client_id=client.id 
    left join LUcourt on LUcourt.id=kase.court_id 
    where date_affidavit_filed is not null and date_affidavit_filed !='' order by servername; 
 
+----+-------------+---------+--------+----------------------+---------+---------+-----------------------+--------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys  | key  | key_len | ref     | rows | Extra          | 
+----+-------------+---------+--------+----------------------+---------+---------+-----------------------+--------+----------------------------------------------+ 
| 1 | SIMPLE  | job  | ALL | date_affidavit_filed | NULL | NULL | NULL     | 365212 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | kase | eq_ref | PRIMARY    | PRIMARY | 4  | pserve.job.kase_id |  1 |            | 
| 1 | SIMPLE  | server | eq_ref | PRIMARY    | PRIMARY | 4  | pserve.job.server_id |  1 |            | 
| 1 | SIMPLE  | client | eq_ref | PRIMARY    | PRIMARY | 4  | pserve.kase.client_id |  1 |            | 
| 1 | SIMPLE  | LUcourt | eq_ref | PRIMARY    | PRIMARY | 4  | pserve.kase.court_id |  1 |            | 
+----+-------------+---------+--------+----------------------+---------+---------+-----------------------+--------+----------------------------------------------+
+0

Avez-vous des index sur vos tables? – andrewsi

+0

Cela pourrait être une question pour http://dba.stackexchange.com/ au lieu de StackOverflow. – Fluffeh

+0

Vous utilisez des jointures à gauche. Attendez-vous des valeurs null? – Arjan

Répondre

1

Vérifiez que vous avez des index sur les colonnes suivantes. job.kase_id ou job.server_id

Vous commandez également par un champ calculé qui n'est pas optimal. Peut-être commander par un champ avec index.

Si vous souhaitez conserver ce tri exact, vous pouvez ajouter un champ dans le DB pour cette valeur. Et remplissez-le avec des valeurs appropriées ou configurez un déclencheur sur le DB pour le remplir automatiquement pour vous.

+0

Le 'Using filesort' est probablement le bit qui le ralentit au diable - je suis juste incapable de dire pourquoi (et il n'est pas toujours lié à un index simple). – Fluffeh

0

Lorsque vous écrivez,

where date_affidavit_filed is not null and date_affidavit_filed !='' 

vous pratiquement sélectionnez la plupart des lignes. Ou au moins tellement que cela ne vaut pas la peine de passer par l'indexation. Le planificateur de requêtes voit qu'il est un index impliquant date_affidavit_filed, mais décide de ne pas l'utiliser et aller avec la clause WHERE, qui implique seulement date_affidavit_filed; Nous savons donc que ce n'est pas une question clé, cela doit être un problème de cardinalité.

| 1 | SIMPLE  | job  | ALL | date_affidavit_filed | NULL | NULL | NULL     | 365212 | Using where; Using temporary; Using filesort | 

Vous pouvez essayer d'optimiser en créant un index sur

date_affidavit_filed, kase_id, server_id 

dans cet ordre. Combien de lignes sont renvoyées par la requête?

0

Vous sélectionnez tout ce qui n'est pas vraiment vide. Cela signifie vraiment tout. Je ne sais pas combien de lignes de données vous avez, mais il y a beaucoup à faire. Essayez de restreindre votre requête à une plage de dates ou à un client spécifique.

Si vous avez vraiment besoin de tout, ne le publiez pas une ligne après l'autre, mais créez une grande chaîne dans le logiciel que vous utilisez pour sortir avec tout le formatage, puis lorsque vous avez fini de parcourir les résultats et vous avez construit les données que vous souhaitez produire, vous pouvez les sortir en une seule fois.

Vous pouvez également utiliser la pagination. Ajoutez simplement limit 0,30 à la page 1, limit 30,30 à la page deux, etc. et laissez l'utilisateur parcourir les pages.

1

Cela peut accélérer l'ordre par:

CREATE INDEX namefull ON server (namefirst,namelast); 

si vous faites ORDER BY (server.namefirst, server.namelast) au lieu de ORDER BY servername, qui devrait produire la même sortie.

Vous pouvez également créer des index sur chaque table de tout champ qui vous reste, ce qui peut également améliorer les performances de votre requête.