Mysql 计数查询需要很多时间

Mysql 计数查询需要很多时间,mysql,sql,Mysql,Sql,我的数据库mysql中有61K行,我试图进行计数,但查询需要4秒钟,我觉得太多了 select count( distinct appeloffre0_.ID_APPEL_OFFRE) from ao.appel_offre appeloffre0_ inner join ao.lot lots1_ on appeloffre0_.ID_APPEL_OFFRE=lots1_.ID_APPEL_OFFRE inner join ao.lieu_execution lieuexecut2_ o

我的数据库
mysql
中有61K行,我试图进行计数,但查询需要4秒钟,我觉得太多了

select count( distinct appeloffre0_.ID_APPEL_OFFRE) 
from ao.appel_offre appeloffre0_ 
inner join ao.lot lots1_ on appeloffre0_.ID_APPEL_OFFRE=lots1_.ID_APPEL_OFFRE 
inner join ao.lieu_execution lieuexecut2_ on appeloffre0_.ID_APPEL_OFFRE=lieuexecut2_.appel_offre 
inner join ao.acheteur acheteur3_ on appeloffre0_.ID_ACHETEUR=acheteur3_.ID_ACHETEUR 
inner join ao.ao_activite aoactivite4_ on appeloffre0_.ID_APPEL_OFFRE=aoactivite4_.ID_APPEL_OFFRE
我的查询结果:

+----------------------------------------------+
| count( distinct appeloffre0_.ID_APPEL_OFFRE) |
+----------------------------------------------+
|                                        61100 |
+----------------------------------------------+
1 row in set (4.35 sec)
为什么在
explain
cmd表
appeloffre0
中使用键
appel\u offre\u ibfk\u 2
,它是FK列
ID\u acheer
上的索引

+----+-------------+--------------+--------+----------------------------+--------------------+---------+--------------------------------+-------+--------------------------+
| id | select_type | table        | type   | possible_keys              | key                | key_len | ref                            | rows  | Extra                    |
+----+-------------+--------------+--------+----------------------------+--------------------+---------+--------------------------------+-------+--------------------------+
|  1 | SIMPLE      | appeloffre0_ | index  | PRIMARY,appel_offre_ibfk_2 | appel_offre_ibfk_2 | 4       | NULL                           | 60031 | Using index              |
|  1 | SIMPLE      | acheteur3_   | eq_ref | PRIMARY                    | PRIMARY            | 4       | ao.appeloffre0_.ID_ACHETEUR    |     1 | Using index              |
|  1 | SIMPLE      | lieuexecut2_ | ref    | fk_ao_lieuex               | fk_ao_lieuex       | 4       | ao.appeloffre0_.ID_APPEL_OFFRE |     1 | Using index              |
|  1 | SIMPLE      | aoactivite4_ | ref    | ao_activites_ao_fk         | ao_activites_ao_fk | 4       | ao.lieuexecut2_.appel_offre    |     3 | Using where; Using index |
|  1 | SIMPLE      | lots1_       | ref    | FK_LOT_AO                  | FK_LOT_AO          | 4       | ao.lieuexecut2_.appel_offre    |     5 | Using where; Using index |
+----+-------------+--------------+--------+----------------------------+--------------------+---------+--------------------------------+-------+--------------------------+
5 rows in set (0.00 sec)
显示来自appel_offre的索引

+-------------+------------+--------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table       | Non_unique | Key_name           | Seq_in_index | Column_name         | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------+------------+--------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| appel_offre |          0 | PRIMARY            |            1 | ID_APPEL_OFFRE      | A         |       60953 |     NULL | NULL   |      | BTREE      |         |               |
| appel_offre |          1 | appel_offre_ibfk_1 |            1 | ID_APPEL_OFFRE_MERE | A         |           2 |     NULL | NULL   | YES  | BTREE      |         |               |
| appel_offre |          1 | appel_offre_ibfk_2 |            1 | ID_ACHETEUR         | A         |           2 |     NULL | NULL   |      | BTREE      |         |               |
| appel_offre |          1 | appel_offre_ibfk_3 |            1 | USER_SAISIE         | A         |           2 |     NULL | NULL   | YES  | BTREE      |         |               |
| appel_offre |          1 | appel_offre_ibfk_4 |            1 | USER_VALIDATION     | A         |           2 |     NULL | NULL   | YES  | BTREE      |         |               |
| appel_offre |          1 | ao_fk_3            |            1 | TYPE_MARCHE         | A         |           2 |     NULL | NULL   | YES  | BTREE      |         |               |
| appel_offre |          1 | ao_fk_5            |            1 | USER_CONTROLE       | A         |           2 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------------+------------+--------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
7 rows in set (0.03 sec)
  • 如何使用索引运行快速计数查询

  • 当我们有多个连接时,如何使用索引

  • 当我们有多个连接和多个搜索时,如何使用索引 询问


  • 不要在计数中使用
    distinct
    ,而是尝试用
    exists
    条件替换1对多的内部联接

    例如,如果
    lot.ID\u APPEL\u OFFRE
    不是唯一的,则删除内部联接

    inner join ao.lot lots1_ on appeloffre0_.ID_APPEL_OFFRE=lots1_.ID_APPEL_OFFRE 
    
    并在where子句中添加exists条件

    where exists (select 1 from ao.lot lots_1 where appeloffre0_.ID_APPEL_OFFRE=lots1_.ID_APPEL_OFFRE)
    

    谢谢@FuzzyTree它将我的时间缩短到0.7秒,你能回答我的2分和3分吗?因为我将使用具有多个联接的多条件搜索。如果可以的话,你可以给我一首很好的图图。@Youssef根据你的解释输出,看起来你已经在多重连接/where标准中正确地使用了索引。似乎在添加了一些where子句之后,又花了一段时间来检查这里