Índices fazem uma enorme diferença no mysql, uma consulta que levou 15 minutos com um conjunto errado de índices levou 0,2 segundos com os corretos, mas é encontrar o equilíbrio certo que geralmente é o problema. Naturalmente, sem alguns dados de amostra, é muito difícil dizer se a solução abaixo economizará tempo, mas em teoria deveria.
Para responder às suas perguntas, eu redesenharia as tabelas assim:
CREATE TABLE `product_all` (
`prod_id` INT( 10 ) NOT NULL,
`ref_id` INT( 10) NOT NULL,
`date` DATE NOT NULL ,
`buy_link` BLOB NOT NULL ,
`sale_price` FLOAT NOT NULL,
PRIMARY KEY (prod_id, ref_id) ,
INDEX date_Index (`date` ASC),
UNIQUE INDEX prod_price_Index (prod_id ASC, sale_price ASC)
) ENGINE = MYISAM ;
CREATE TABLE `product_info` (
`prod_id` INT( 10 ) NOT NULL AUTO_INCREMENT,
`prod_name` VARCHAR( 200 ) NOT NULL,
`brand` VARCHAR( 50 ) NOT NULL,
`retail_price` FLOAT NOT NULL,
`category` INT( 3 ) NOT NULL,
`gender` VARCHAR( 1 ) NOT NULL,
`type` VARCHAR( 10 ) NOT NULL,
PRIMARY KEY (prod_id) ,
UNIQUE INDEX prod_id_name_Index (prod_id ASC, prod_name ASC),
INDEX category_Index (category ASC),
INDEX gender_Index (gender ASC)
) ENGINE = MYISAM ;
SELECT product_info.*, MIN(product_all.sale_price) as sale_price, product_all.buy_link
FROM product_info
NATURAL JOIN (SELECT * FROM product_all WHERE product_all.date = '2010-09-30') as product_all
WHERE (product_info.category = 2
AND product_info.gender = 'W' )
GROUP BY product_all.prod_id
ORDER BY MIN(product_all.sale_price) ASC LIMIT 13
O ganho de desempenho aqui é obtido com a indexação dos principais campos que estão sendo unidos e são apresentados na cláusula where. Pessoalmente, eu iria com sua primeira consulta, pois quando você pensa sobre isso, deve ter um desempenho melhor.
Tanto quanto eu entendo o que está acontecendo na primeira e segunda consulta:
- A primeira consulta está sendo filtrada por uma subconsulta antes de fazer a junção natural, o que significa que ela só une os dados resultantes e não a tabela inteira.
- A segunda consulta está juntando toda a segunda tabela e, em seguida, filtrando as linhas resultantes de todo o lote de volta para o que você deseja.
Como regra geral, normalmente você deseja adicionar índices em seus principais campos de junção e também os campos que você mais usa nas cláusulas where. Também coloquei alguns índices exclusivos em alguns dos campos que você deseja consultar regularmente, como prod_id_name_Index.
Se isso não melhorar seu desempenho, se você puder postar alguns dados fictícios para brincar, talvez consiga uma solução mais rápida que possa comparar.
Aqui é um artigo que passa por indexação para desempenho no mysql, vale a pena ler se quiser saber mais.
Boa sorte!
EDIT:Sua pergunta final eu perdi da primeira vez, a resposta é que, se você indexar os principais campos de junção, mudar para onde só afetará ligeiramente o desempenho geral, mas os índices exclusivos que coloquei nas tabelas devem levar em conta o maioria das coisas nas quais você deseja basear as consultas. A principal coisa a ser lembrada é que se você consulta ou se junta a um campo com frequência, ele deve ser indexado, mas consultas menores e alterações na ordem por você não devem se preocupar em realinhar sua estratégia de indexação.