Estou usando um banco de dados MySQL 5.1.69-log para fins de análise.
Eu projetei meu banco de dados em um esquema de estrela. Todas as tabelas estão usando InnoDB. Meuinnodb_buffer_pool_size=2Gb
Esta é a consulta que estou executando:
select
`dw_dimension_criteria`.`id` as `c0`,
count(distinct `dw_fact_program_attendance`.`client_id`) as `m0`
from
`dw_dimension_criteria` as `dw_dimension_criteria`,
`dw_fact_program_attendance` as `dw_fact_program_attendance`
where
`dw_fact_program_attendance`.`criteria_id` = `dw_dimension_criteria`.`id`
group by `dw_dimension_criteria`.`id`;
O EXPLAIN dá o seguinte:
+----+-------------+----------------------------+-------+---------------+--------------+---------+-----------------------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------------+-------+---------------+--------------+---------+-----------------------------------------+--------+-------------+
| 1 | SIMPLE | dw_dimension_criteria | index | PRIMARY | PRIMARY | 2 | NULL | 1 | Using index |
| 1 | SIMPLE | dw_fact_program_attendance | ref | criteria_id | criteria _id | 2 | clarity_nevada.dw_dimension_criteria.id | 417669 | |
+----+-------------+----------------------------+-------+---------------+--------------+---------+-----------------------------------------+--------+-------------+
e o comando SHOW PROFILE o seguinte:
+----------------------+-----------+
| Status | Duration |
+----------------------+-----------+
| starting | 0.000117 |
| checking permissions | 0.000035 |
| checking permissions | 0.000009 |
| Opening tables | 0.000022 |
| System lock | 0.000004 |
| Table lock | 0.000011 |
| init | 0.000032 |
| optimizing | 0.000012 |
| statistics | 0.000045 |
| preparing | 0.000017 |
| executing | 0.000043 |
| Sorting result | 0.000005 |
| Sending data | 12.847928 |
| end | 0.000103 |
| removing tmp table | 0.000016 |
| end | 0.000016 |
| query end | 0.000005 |
| freeing items | 0.000114 |
| logging slow query | 0.000003 |
| logging slow query | 0.000097 |
| cleaning up | 0.000012 |
+----------------------+-----------+
Não entendo esses 12 segundos. Não entendo se pertence ao resultado da classificação ou ao envio de dados . Tentei ajustar, sort_buffer_size
mas sem sucesso flagrante. A tabela de fatos conta com cerca de 7 milhões de linhas.
Onde devo procurar para diminuir esses 12 segundos para um tempo mais razoável?
Se houver uma chave estrangeira
dw_fact_program_attendance(criteria_id)
dissoREFERENCES dw_dimension_criteria(id)
, não há necessidade de unir as duas tabelas (mas o otimizador ainda não é inteligente o suficiente para entender isso). Você pode ter apenas uma tabela eGROUP BY criteria_id
:Um índice sobre
(criteria_id, client_id)
ajudaria na eficiência.