Eu uso o MySQL 5.6 e tenho duas tabelas cada uma com 16 milhões de linhas:
CREATE TABLE IF NOT EXISTS `newsstudios` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16855382 ;
CREATE TABLE IF NOT EXISTS `newsstudio_categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`newsstudio_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `newsstudio_id` (`newsstudio_id`),
KEY `category_id` (`category_id`),
KEY `newsstudio_id_category_id` (`newsstudio_id`,`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16864013 ;
Eu tenho uma consulta com pedido por order by newsstudios.id ASC
:
SELECT SQL_NO_CACHE id FROM `newsstudios` WHERE exists
(
select newsstudio_id from newsstudio_categories
where newsstudios.id=newsstudio_categories.newsstudio_id
and newsstudio_categories.category_id in (1303,1313,1323,1333,1343,632)
)
order by newsstudios.id limit 5;
o resultado dessa consulta é:
+------+
| id |
+------+
| 27 |
| 47 |
| 87 |
| 110 |
| 181 |
+------+
5 rows in set (0.19 sec)
mas quando mudo a direção do order by para DESC
o tempo de execução da query diminui 100 vezes:
+------+
| id |
+------+
| 98232|
| 98111|
| 95222|
| 88132|
| 78181|
+------+
5 rows in set (21 sec)
Primeiro: por que essa mudança na direção do pedido causa essa diferença enorme de desempenho?
Segundo: antes desta consulta eu tentei LEFT JOIN
e WHERE IN
consultas em vez de WHERE EXISTS
, mas eles têm resultado duplicado que devo usar GROUP BY
que causa using filesort
e using temporary
que diminui muito o desempenho. Você tem alguma sugestão para que a consulta tenha melhor desempenho?
Se as diferentes categorias que você está pesquisando não forem muitas e você puder criar a consulta mais complexa, isso usará um índice
(category_id, newsstudio_id)
e espero que seja mais eficiente do que sua consulta anterior, comASC
ouDESC
escolha.É um pouco mais complexo de construir e espero que a eficiência diminua se o número de categorias for dezenas ou centenas:
Como o ypercube disse em seu comentário, seu índice deve ter um desempenho melhor neste caso se os campos estiverem invertidos.
Além disso, desde que cada arquivo
newsstudio_categories
.newsstudio_id
tem pelo menos uma linha correspondente emnewsstudios
.id
(não garantido pelo seu esquema, mas parece provável), então você poderia fazer uma consulta que olhasse apenas paranewsstudio_categories
ou