2016-10-10 26 views
0

我正在处理一个拥有大量数据的项目。数据存储在MySql Db中。 我想从几张表中分页读取记录。其中一张表有超过2百万条记录导致页面冻结很长时间。有时该页面根本无法加载。MySql:增加分页的查询执行时间

我使用来获取记录的查询:

SELECT 
    EN.`MRN`, 
    P.`FNAME`, 
    P.`LNAME`, 
    P.`MI`, 
    P.`SSC`, 
    sum(EN.`AMOUNT`) AS `TOTAL_AMOUNT` 
FROM `table_1` AS EN 
INNER JOIN `table_2` AS P ON EN.`MRN` = P.`MRN` 
GROUP BY EN.`MRN`,P.`FNAME`, P.`LNAME`,P.`MI`,P.`SSC` 
HAVING sum(EN.`AMOUNT`) > 0 
ORDER BY P.`LNAME` 

通过此查询我得到的总记录数的分页工作。然后我再次运行此查询以获取实际记录:

SELECT 
    EN.`MRN`, 
    P.`FNAME`, 
    P.`LNAME`, 
    P.`MI`, 
    P.`SSC`, 
    sum(EN.`AMOUNT`) AS `TOTAL_AMOUNT` 
FROM `table_1` AS EN 
INNER JOIN `table_2` AS P ON EN.`MRN` = P.`MRN` 
GROUP BY EN.`MRN`,P.`FNAME`, P.`LNAME`,P.`MI`,P.`SSC` 
HAVING sum(EN.`AMOUNT`) > 0 
ORDER BY P.`LNAME` 
LIMIT 0, 100 

如何使此查询更快地工作。因为第一次执行查询需要很长时间才能获取记录总数。

+0

使用计数来计数记录比选择所有结果更快,然后获得计数。 SELECT count(*)FROM'table_1' AS EN INNER JOIN'table_2' AS P ON EN.'MRN' = P.'MRN' GROUP BY EN.'MRN',P.'FNAME',P。 'LNAME',P.'MI',P.'SSC' HAVING sum(EN.'AMOUNT')> 0 ORDER BY P.'LNAME' –

+0

@pkdq您是否检查过表table_1中有索引的列你选择?如果你没有给出索引,那么把它分配给你主要使用的列。这会让你的执行速度更快。 –

+0

您使用innodb或myisam表吗? – Naruto

回答

0

最好将total_amount与查询分开,因为这是涉及所有记录的唯一值。你可以在加载页面时调用它。我假设table_1中的所有记录都是有效的。

SELECT sum(EN.`AMOUNT`) AS `TOTAL_AMOUNT` FROM `table_1` AS EN 
HAVING sum(EN.`AMOUNT`) > 0 

然后每次翻页时都会得到查询结果。这应该只返回从记录0开始的10条记录。

SELECT 
EN.`MRN`, 
P.`FNAME`, 
P.`LNAME`, 
P.`MI`, 
P.`SSC` 
FROM `table_1` AS EN 
INNER JOIN `table_2` AS P ON EN.`MRN` = P.`MRN` 
GROUP BY EN.`MRN`,P.`FNAME`, P.`LNAME`,P.`MI`,P.`SSC` 
HAVING sum(EN.`AMOUNT`) > 0 
ORDER BY P.`LNAME` 
LIMIT 10 OFFSET 0 

希望这会有所帮助。

0

有几件事情可以做,使这个速度快:

  • 使用EXPLAIN,以确保您的索引设置正确/设定正确的指标。
  • 只使用SQL_CALC_FOUND_ROWS执行一次复杂查询。
  • HAVING语句中使用TOTAL_AMOUNT别名可避免执行两次计算。

MySQL会做一些优化和缓存本身,所以它们可能并不都具有相同的影响。