Tenho uma dúvida sobre o uso de índices compostos em uma tabela. Tenho duas tabelas:
CREATE TABLE `test_table` (
`user_id` bigint unsigned NOT NULL AUTO_INCREMENT,
`dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `user_id` (`user_id`)
);
CREATE TABLE `test_table_2` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`id_user` int unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_user` (`id_user`,`dt`)
);
Estou tentando usar um índice composto em junções e também em subconsultas, no entanto, não consigo descobrir uma coisa. Por que, não importa o quanto eu tente, apenas o lado esquerdo do índice é obtido? Entendo que uma correspondência exata é importante para uma junção, mas não entendo o fato de que em uma amostra em uma tabela com um índice, ao usar WHERE de dois campos, mesmo usando um intervalo, o índice completo é obtido.
EXPLAIN SELECT
*
FROM test_table_2 t
WHERE t.id_user = 1 AND t.dt >= GREATEST('2024-09-10','2024-09-20');
EXPLAIN
SELECT
t.user_id,
t.dt,
MIN(tt2.id) AS mn_id
FROM test_table t
JOIN test_table_2 tt2 ON t.user_id= tt2.id_user
WHERE tt2.id_user = t.user_id
AND tt2.dt >= GREATEST(t.dt, '2024-01-01')
GROUP BY 1,2;
EXPLAIN SELECT ...
não fornece todas as informações que você pensa que fornece. Em particular, ele falha em indicar que oINDEX
pode realmente ser usado (para sua primeira consulta). Observe aRows
coluna e/ou observe o valor 'rows' emEXPLAIN ANALYZE SELECT ...
. Então, altere a data (emSELECT
) para incluir mais (ou menos) linhas e veja como as "rows" mudam.A segunda consulta é mais complexa por causa da mistura de colunas de ambas as tabelas em
WHERE
:BIGINT
ocupa 8 bytes.