Question

I have a table with 40,000,000 rows, and I'm trying to optimize my query, because takes too long.
First, this is my table:
CREATE TABLE resume (
yearMonth char(6) DEFAULT NULL,
type char(1) DEFAULT NULL,
agen_o char(5) DEFAULT NULL,
tar char(2) DEFAULT NULL,
cve_ent char(1) DEFAULT NULL,
cve_mun char(3) DEFAULT NULL,
cve_reg int(1) DEFAULT NULL,
id_ope char(1) DEFAULT NULL,
ope_tip char(2) DEFAULT NULL,
ope_cve char(3) DEFAULT NULL,
cob_u int(9) DEFAULT NULL,
tot_imp bigint(15) DEFAULT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


This is my query:
SELECT m.name_ope AS cve,
SUBSTRING(r.yearMonth,5,2) AS period,
COUNT(DISTINCT(CONCAT(r.agen_ope,r.cve_ope))) AS num,
SUM(CASE WHEN r.type='A' THEN r.cob_u ELSE 0 END) AS tot_u,
FROM resume r, media m
WHERE CONCAT(r.id_ope,SUBSTRING(r.ope_cve,3,1))=m.ope_cve AND
r.type IN ('C','D','E') AND
SUBSTRING(r.yearMonth,1,4)='2012' AND
r.id_ope='X' AND
SUBSTRING(r.ope_cve,1,2) IN (SELECT cve_med FROM catNac WHERE numero='0')
GROUP BY SUBSTRING(r.yearMonth,5,2),SUBSTRING(r.ope_cve,3,1)
ORDER BY SUBSTRING(r.yearMonth,5,2),SUBSTRING(r.ope_cve,3,1)


So, I added an index with these fields: id_ope, yearMonth, agen_o, because I have other's queries that have this fields in WHERE, with this order
Now my explain output:
1 PRIMARY r ref indice indice 2 const 14774607 Using where; Using filesort
So i added another index with yearMonth, ope_cve, but I still have "using filesort". How can I optimize this?
Thanks

Était-ce utile?

La solution

Without modifying your table structure, if you have an index on yearMonth, you can try this:

SELECT m.name_ope AS cve,
SUBSTRING(r.yearMonth,5,2) AS period,
COUNT(DISTINCT(CONCAT(r.agen_ope,r.cve_ope))) AS num,
SUM(CASE WHEN r.type='A' THEN r.cob_u ELSE 0 END) AS tot_u,
FROM resume r, media m
WHERE CONCAT(r.id_ope,SUBSTRING(r.ope_cve,3,1))=m.ope_cve AND
r.type IN ('C','D','E') AND
r.yearMonth LIKE '2012%' AND
r.id_ope='X' AND
SUBSTRING(r.ope_cve,1,2) IN (SELECT cve_med FROM catNac WHERE numero='0')
GROUP BY r.yearMonth,SUBSTRING(r.ope_cve,3,1)

The changes:

  • Using r.yearMonth LIKE '2012%' should allow an index to be used for that part of your where clause.
  • Since you're already filtering out every year but 2012, you can group by GROUP BY r.yearMonth alone.
  • The ORDER BY clause is not needed since MySQL sorts on GROUP BY, unless you include ORDER BY NULL
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top