如何改进检索11.2m数据的mysql查询?

时间:2016-03-17 00:39:37

标签: mysql

select tblfarmerdetails.ncode,
tblfarmerdetails.region,tblfarmerdetails.province, tblfarmerdetails.municipality,
concat(tblfarmerdetails.farmerfname, ' ', tblfarmerdetails.farmerlname) as nameoffarmer,
 concat(tblfarmerdetails.spousefname, ' ',tblfarmerdetails.spouselname) as nameofspouse, tblstatus.statusoffarmer from tblfarmerdetails
 INNER Join
 tblstatus on tblstatus.ncode = tblfarmerdetails.ncode where tblstatus.ncode = tblfarmerdetails.ncode order by tblfarmerdetails.region

检索11.2m数据需要很长时间。我将如何改进此查询?

1 个答案:

答案 0 :(得分:2)

首先,对查询进行格式化,使其可读或至少可被人识别。

  SELECT f.ncode
       , f.region
       , f.province
       , f.municipality
       , CONCAT(f.farmerfname,' ',f.farmerlname) AS nameoffarmer
       , CONCAT(f.spousefname,' ',f.spouselname) AS nameofspouse
       , s.statusoffarmer
    FROM tblfarmerdetails
    JOIN tblstatus s
      ON s.ncode = f.ncode
   ORDER BY f.region

可能需要花费大量时间来执行“使用filesort”操作,以按ORDER BY子句中指定的顺序对所有行进行排序。如果没有前导列为region的索引,肯定会发生排序操作。

有适当的索引,例如

... ON tblfarmerdetails (region, ... )

意味着MySQL可以使用索引“按顺序”返回行,而无需进行排序操作。

如果MySQL有一个“覆盖索引”可用,即一个索引包含查询中表引用列的所有,MySQL可以利用该索引来满足查询而不需要访问基础表格中的页面。

但考虑到列的数量,以及其中一些列的大小可能是VARCHAR的可能性,这可能是不可能的或不可行的:

... ON tblfarmerdetails (region, ncode, province, municipality, farmerfname, farmerlname,  spousefname, spouselname)

(MySQL确实对indexex有一些限制。“覆盖索引”的目标是避免查找表中的页面。)

确保MySQL知道ncode中的tblstatus是唯一的。{1}}。无论是PRIMARY KEY还是UNIQUE索引。

我们怀疑tblstatus表包含少量行,因此连接操作可能并不昂贵。但是,以ncode为主要列的适当覆盖索引不会受到影响:

 ... ON tblstatus (ncode, statusoffarmer) 

如果MySQL必须执行“使用filesort”操作来获取所排序的行(以满足ORDER BY子句),在大型集合上,该操作可以溢出到磁盘,并且可以添加(有时显着) )到经过的时间。

查询生成的结果集必须传输到客户端。这也可能需要一些时钟。

客户端必须对返回的行执行某些操作。

你确定你真的需要返回11.2M行吗?或者,你只需要前几千行吗?

考虑在查询中添加LIMIT子句。

这些lnamefname列有多长?您是否需要MySQL为您进行连接,或者可以在行进行时在客户端上完成。

MySQL可能必须执行“使用临时”来保存具有连接结果的行。并且MySQL可能为该返回列分配足够的空间,以保持lname +最大可能长度与fname的最大可能长度。如果这是一个多字节字符字符集,那么将在单个字节字符集上将存储空间增加一倍或三倍。

要真正了解正在发生的事情,您需要查看查询执行计划。通过在SELECT语句前面加上关键字EXPLAIN

来获得它
EXPLAIN SELECT ... 

该输出将显示MySQL将要执行的操作,它将使用哪些索引。有了MySQL优化器可以执行的操作的知识,我们可以用它来做出一些非常好的猜测,以获得最大的收益。