2015-01-04 298 views
0

我有我的數據庫中有61K行mysql,我試着做一個計數,但查詢需要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_offre_ibfk_2這是對FK列ID_ACHETEUR一個指數?

+----+-------------+--------------+--------+----------------------------+--------------------+---------+--------------------------------+-------+--------------------------+ 
| 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) 
  1. 如何使用指數跑得快數查詢索引?

  2. 如何在我們有多個連接時使用索引?

  3. 如何使用索引當我們有多個連接和多個搜索 查詢?

回答

2

而是在數使用distinct的嘗試更換你的1對多內與exists條件加入。

例如,如果lot.ID_APPEL_OFFRE不是唯一的,然後取出內部聯接

inner join ao.lot lots1_ on appeloffre0_.ID_APPEL_OFFRE=lots1_.ID_APPEL_OFFRE 

,並添加您的where子句中的存在狀態

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

感謝@FuzzyTree它減少我的時間0.7秒,你能回答我的2點和3點嗎?因爲我將使用多重連接的多標準搜索。如果可以的話,你可以給我一個很好的答案。 – Youssef

+0

@Youssef根據你的解釋輸出,它看起來像你已經正確地使用索引與您的多個加入/其中條件 – FuzzyTree

+0

似乎在添加一些where子句後需要時間再次檢查它在這裏http://stackoverflow.com/questions/ 27784778 /慢計數查詢與-where子句 – Youssef