mysql使用order by缓慢复杂查询

时间:2012-09-13 14:44:59

标签: mysql join percona

即使没有order by,下面的查询也很慢,我无法弄清楚原因。我猜这是where date_affidavit_file,但我怎样才能使用order by来快速完成?也许job_id上的sublect与where匹配,然后将其传递给代码的其余部分,但我仍然需要通过服务器命令这样的服务器名称。有什么建议吗?

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 |                                              | 
+----+-------------+---------+--------+----------------------+---------+---------+-----------------------+--------+----------------------------------------------+

4 个答案:

答案 0 :(得分:1)

检查以下列是否有索引。 job.kase_idjob.server_id

此外,您按计算字段排序并非最佳。也许用带索引的字段排序。

如果您需要保留这种确切的排序,您可能希望在数据库中为该值添加一个字段。并使用适当的值填充它或在DB上设置触发器以自动为其填充。

答案 1 :(得分:1)

这可以通过以下方式加快订单:

CREATE INDEX namefull ON server (namefirst,namelast);

如果您执行ORDER BY (server.namefirst, server.namelast)而不是ORDER BY servername,则应生成相同的输出。

您还可以在要加入的任何字段上的每个表上创建索引,这也可以提高查询的性能。

答案 2 :(得分:0)

当你写作时,

where date_affidavit_filed  is not null and date_affidavit_filed  !=''

你实际上是在选择大部分行。或者至少这么多,以至于不值得通过索引编制。查询计划程序看到涉及date_affidavit_filed的索引,但决定不使用它并使用WHERE子句,该子句仅涉及date_affidavit_filed;所以我们知道这不是一个关键问题,它必须是一个基数问题。

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

您可以尝试通过在

上创建索引来优化此功能
date_affidavit_filed, kase_id, server_id

按此顺序。查询返回了多少行?

答案 3 :(得分:0)

你正在选择那些非空的东西。 这真的意味着一切。 我不知道你有多少行数据,但要经历很多。

尝试将查询缩小到日期范围或特定客户端。

如果你真的需要一切,不要在一段时间之后输出一行,而是在你用来输出所有格式的软件中建立一个大字符串,然后当你完成循环结果并且你已经构建了您希望输出的数据,您可以将它们输出一大段。

您也可以使用分页。 只需在第1页添加limit 0,30,在第2页添加limit 30,30等,然后让最终用户浏览页面。