I have this query:
SELECT p.prodno AS id,
proddesc AS label
FROM product p
JOIN sales s
ON s.custno = 00800
AND s.deptno = 0
AND s.prodno = p.prodno
GROUP BY p.prodno
ORDER BY p.prodno ASC
Explain returns this:
+---+-----------+------+--------+------------------------------------------------------------------------------+------------+------+----------------------------------------+------+---------+------------------------------------+
| 1 | 'SIMPLE' | 'p' | 'ALL' | 'PRIMARY' | '' | '' | '' | 481 | 100.00 | 'Using temporary; Using filesort' |
| 1 | 'SIMPLE' | 's' | 'ref' | 'PRIMARY,in_sales_custnodeptnoprodno,in_sales_deptnocustno,in_sales_custno' | 'PRIMARY' | '6' | 'const,const,bkp_teststats2.p.PRODNO' | 93 | 100.00 | 'Using index' |
+---+-----------+------+--------+------------------------------------------------------------------------------+------------+------+----------------------------------------+------+---------+------------------------------------+
As you see there is no index used in the first row for PRODNO, but the table schema has index on it.
CREATE TABLE IF NOT EXISTS `product` (
`PRODNO` decimal(4,0) unsigned zerofill NOT NULL DEFAULT '0000',
`PRODDESC` char(21) NOT NULL DEFAULT '',
`UPCCODE12` decimal(12,0) unsigned zerofill NOT NULL DEFAULT '000000000000',
PRIMARY KEY (`PRODNO`)
)
And sales has these keys:
PRIMARY KEY (`CUSTNO`,`DEPTNO`,`PRODNO`,`ARDATE8N`),
KEY `in_sales_custnodeptnoprodno` (`CUSTNO`,`DEPTNO`,`PRODNO`),
KEY `in_sales_deptnocustno` (`DEPTNO`,`CUSTNO`),
KEY `in_sales_custno` (`CUSTNO`),
I would like to drop Using temporary; Using filesort because the above query takes 14 seconds on a 50G data table.
Update:
Problem: I want to get a unique product list that have sales data for a given custno and deptno.
The database has to check every row in the
producttable to satisfy your query. If it used the index, it would have to go back to the main table for every row to pick upproddesc. Going back to the main table (a “bookmark lookup”) is quite expensive. So the query optimizer chooses to scan and sort the main table, which seems like a good choice to me.If you omit
proddescfrom the result, the query only requiresprodno. In that case the query optimizer will probably use the index.You could also expand the index on
productsfrom(prodno)to(prodno, proddesc). Expanded this way, the index can satisfy the query without table lookups.