Mysql
 sql >> Base de données >  >> RDS >> Mysql

Optimisation des performances MySQL :trier par champ datetime

Créez un index composite soit sur postings (is_active, post_date) (dans cet ordre).

Il sera utilisé à la fois pour filtrer sur is_active et commande par post_date .

MySQL doit afficher REF méthode d'accès sur cet index dans EXPLAIN EXTENDED .

Notez que vous avez une RANGE condition de filtrage sur user_offtopic_count , c'est pourquoi vous ne pouvez pas utiliser d'index sur ce champ à la fois pour le filtrage et pour le tri par un autre champ.

En fonction de la sélectivité de votre user_offtopic_count (c'est-à-dire combien de lignes satisfont user_offtopic_count < 10 ), il peut être plus utile de créer un index sur user_offtopic_count et laissez les post_dates être triées.

Pour cela, créez un index composite sur les postings (is_active, user_offtopic_count) et assurez-vous que la RANGE méthode d'accès sur cet index est utilisée.

L'index qui sera le plus rapide dépend de la distribution de vos données. Créez les deux index, FORCE eux et voyez lequel est le plus rapide :

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 */