MySQL的limit和offset优化测试

jerry mysql 2015年09月14日 收藏

例子1:

表t_attorney结构如下,具有30000行数据

  1. mysql> desc t_applicant;
  2. +---------------+--------------+------+-----+---------+----------------+
  3. | Field         | Type         | Null | Key | Default | Extra          |
  4. +---------------+--------------+------+-----+---------+----------------+
  5. | id            | int(11)      | NO   | PRI | NULL    | auto_increment |
  6. | internalNo    | varchar(45)  | YES  |     | NULL    |                |
  7. | firstName     | varchar(45)  | YES  |     | NULL    |                |
  8. | lastName      | varchar(45)  | YES  |     | NULL    |                |
  9. | email         | varchar(100) | YES  |     | NULL    |                |
  10. | address       | varchar(500) | YES  |     | NULL    |                |
  11. | telNo         | varchar(60)  | YES  |     | NULL    |                |
  12. | certificateNo | varchar(60)  | YES  |     | NULL    |                |
  13. | nationality   | varchar(60)  | YES  |     | NULL    |                |
  14. | idCardNo      | varchar(45)  | YES  |     | NULL    |                |
  15. +---------------+--------------+------+-----+---------+----------------+
  16. 10 rows in set (0.00 sec)

两种查询方式:


  1. mysql> select a.internalNo, a.firstName, a.lastName, a.email, a.address, a.telNo, a.certificateNo, a.nationality, a.idCardNo from t_ applicant a inner join (select id from t_ applicant order by id desc limit 18000,15) as a2 using(id) ;
  2.  
  3. 15 rows in set (0.03 sec)
  4.  
  5.  
  6. mysql> select a.internalNo, a.firstName, a.lastName, a.email, a.address, a.telNo, a.certificateNo, a.nationality, a.idCardNo from t_applicant a order by id desc limit 18000,15;
  7.  
  8. 15 rows in set (0.08 sec)

两种查询方式,第一种查询平均耗时0.03秒左右;而第二种平均耗时0.08秒左右。


例子2:

 

表t_patentCase结构如下,具有90000行数据。

  1. mysql> desc t_patentCase;
  2. +-------------------+-------------+------+-----+---------+----------------+
  3. | Field             | Type        | Null | Key | Default | Extra          |
  4. +-------------------+-------------+------+-----+---------+----------------+
  5. | id                | int(11)     | NO   | PRI | NULL    | auto_increment |
  6. | internalNo        | varchar(45) | NO   | MUL | NULL    |                |
  7. | name              | varchar(45) | YES  |     | NULL    |                |
  8. | appliedDate       | datetime    | YES  |     | NULL    |                |
  9. | createdDate       | datetime    | YES  |     | NULL    |                |
  10. | patentCaseType    | int(11)     | YES  |     | NULL    |                |
  11. | firstAttorney_id  | int(11)     | YES  | MUL | NULL    |                |
  12. | secondAttorney_id | int(11)     | YES  |     | NULL    |                |
  13. | firstInventor_id  | int(11)     | YES  | MUL | NULL    |                |
  14. | firstApplicant_id | int(11)     | YES  | MUL | NULL    |                |
  15. | firstContact_id   | int(11)     | YES  | MUL | NULL    |                |
  16. | applicationNo     | varchar(45) | YES  |     | NULL    |                |
  17. +-------------------+-------------+------+-----+---------+----------------+
  18. 12 rows in set (0.03 sec)

视图v_patentCase_summary是t_patentCase左连接另外4张表的结果视图,结构如下:

  1. mysql> desc v_patentCase_summary;
  2. +--------------------------+-------------+------+-----+---------+-------+
  3. | Field                    | Type        | Null | Key | Default | Extra |
  4. +--------------------------+-------------+------+-----+---------+-------+
  5. | id                       | int(11)     | NO   |     | 0       |       |
  6. | internalNo               | varchar(45) | NO   |     | NULL    |       |
  7. | name                     | varchar(45) | YES  |     | NULL    |       |
  8. | patentCaseType           | int(11)     | YES  |     | NULL    |       |
  9. | createdDate              | datetime    | YES  |     | NULL    |       |
  10. | appliedDate              | datetime    | YES  |     | NULL    |       |
  11. | applicationNo            | varchar(45) | YES  |     | NULL    |       |
  12. | firstAttorney_id         | int(11)     | YES  |     | NULL    |       |
  13. | firstAttorney_firstName  | varchar(45) | YES  |     | NULL    |       |
  14. | firstAttorney_lastName   | varchar(45) | YES  |     | NULL    |       |
  15. | secondAttorney_id        | int(11)     | YES  |     | NULL    |       |
  16. | secondAttorney_firstName | varchar(45) | YES  |     | NULL    |       |
  17. | secondAttorney_lastName  | varchar(45) | YES  |     | NULL    |       |
  18. | firstApplicant_id        | int(11)     | YES  |     | NULL    |       |
  19. | firstApplicant_firstName | varchar(45) | YES  |     | NULL    |       |
  20. | firstApplicant_lastName  | varchar(45) | YES  |     | NULL    |       |
  21. | firstInventor_id         | int(11)     | YES  |     | NULL    |       |
  22. | firstInventor_firstName  | varchar(45) | YES  |     | NULL    |       |
  23. | firstInventor_lastName   | varchar(45) | YES  |     | NULL    |       |
  24. | firstContact_id          | int(11)     | YES  |     | NULL    |       |
  25. | firstContact_firstName   | varchar(45) | YES  |     | NULL    |       |
  26. | firstContact_lastName    | varchar(45) | YES  |     | NULL    |       |
  27. +--------------------------+-------------+------+-----+---------+-------+
  28. 22 rows in set (0.00 sec)

两种查询方式:

  1. mysql> select v.id, v.internalNo, v.name, v.patentCaseType, v.createdDate, v.appliedDate, v.applicationNo, v.firstAttorney_id, v.firstAttorney_firstName, v.firstAttorney_lastName, v.secondAttorney_id, v.secondAttorney_firstName, v.secondAttorney_lastName, v.firstApplicant_id, v.firstApplicant_firstName, v.firstApplicant_lastName, v.firstInventor_id, v.firstInventor_firstName, v.firstInventor_lastName, v.firstContact_id, v.firstContact_firstName, v.firstContact_lastName from v_patentCase_summary v right join (select id from t_patentCase order by id desc limit 60000,15) as p on v.id=p.id ;
  2.  
  3. 15 rows in set (1.45 sec)
  4.  
  5.  
  6. mysql> select v.id, v.internalNo, v.name, v.patentCaseType, v.createdDate, v.appliedDate, v.applicationNo, v.firstAttorney_id, v.firstAttorney_firstName, v.firstAttorney_lastName, v.secondAttorney_id, v.secondAttorney_firstName, v.secondAttorney_lastName, v.firstApplicant_id, v.firstApplicant_firstName, v.firstApplicant_lastName, v.firstInventor_id, v.firstInventor_firstName, v.firstInventor_lastName, v.firstContact_id, v.firstContact_firstName, v.firstContact_lastName from v_patentCase_summary v order by id desc limit 60000,15;
  7.  
  8. ? rows in set (??? sec)

两种查询方式,第一种查询平均耗时1.50秒左右;而第二种过了数分钟尚无反应。

小结:

通过以上两个例子可以看出这种方法的效率改善,当然优化无止境,根据以后的具体应用要求,还可以继续优化offset的定位问题。