Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Otimização de desempenho do MySQL:ordem por campo de data e hora


Crie um índice composto em postings (is_active, post_date) (naquela ordem).

Ele será usado tanto para filtrar em is_active e pedidos por post_date .

MySQL deve mostrar REF método de acesso sobre este índice em EXPLAIN EXTENDED .

Observe que você tem um RANGE condição de filtragem sobre user_offtopic_count , é por isso que você não pode usar um índice sobre esse campo tanto na filtragem quanto na classificação por outro campo.

Dependendo de quão seletivo é seu user_offtopic_count (ou seja, quantas linhas satisfazem user_offtopic_count < 10 ), pode ser mais útil criar um índice em user_offtopic_count e deixe os post_dates serem ordenados.

Para fazer isso, crie um índice composto em postings (is_active, user_offtopic_count) e certifique-se de que o RANGE método de acesso sobre este índice é usado.

Qual índice será mais rápido depende da sua distribuição de dados. Crie ambos os índices, FORCE e veja qual é mais rápido:
CREATE INDEX ix_active_offtopic ON postings (is_active, user_offtopic_count);
CREATE INDEX ix_active_date ON postings (is_active, post_date);

SELECT 
    `postings`.`id`, 
    UNIX_TIMESTAMP(postings.post_date) as post_date, 
    `postings`.`link`, 
    `postings`.`title`, 
    `postings`.`author`, 
    `postings`.`excerpt`, 
    `postings`.`long_excerpt`, 
    `feeds`.`title` AS feed_title, 
    `feeds`.`website` AS feed_website
FROM 
    `postings` FORCE INDEX (ix_active_offtopic)
JOIN 
    `feeds` 
ON 
    `feeds`.`id` = `postings`.`feed_id`
WHERE 
    `feeds`.`type` = 1 AND 
    `postings`.`user_offtopic_count` < 10 AND 
    `postings`.`is_active` = 1
ORDER BY 
    `postings`.`post_date` desc
LIMIT 
    15

/* This should show RANGE access with few rows and keep the FILESORT */

SELECT 
    `postings`.`id`, 
    UNIX_TIMESTAMP(postings.post_date) as post_date, 
    `postings`.`link`, 
    `postings`.`title`, 
    `postings`.`author`, 
    `postings`.`excerpt`, 
    `postings`.`long_excerpt`, 
    `feeds`.`title` AS feed_title, 
    `feeds`.`website` AS feed_website
FROM 
    `postings` FORCE INDEX (ix_active_date)
JOIN 
    `feeds` 
ON 
    `feeds`.`id` = `postings`.`feed_id`
WHERE 
    `feeds`.`type` = 1 AND 
    `postings`.`user_offtopic_count` < 10 AND 
    `postings`.`is_active` = 1
ORDER BY 
    `postings`.`post_date` desc
LIMIT 
    15

/* This should show REF access with lots of rows and no FILESORT */