2 votes

Utilisation de Where pendant l'explication pour une requête MySQL

Je dispose d'une table lors de l'exécution d'une requête,

EXPLAIN SELECT `id`
FROM `tblsender`
WHERE `userid` = '6'
AND `astatus` = '1'
AND `sender` = 'ABCDEF'

Je reçois USING WHERE même après avoir été indexé de toutes les manières possibles. Voici mon code final de structure de table.

CREATE TABLE IF NOT EXISTS `tblsender` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sender` varchar(6) NOT NULL,
`astatus` tinyint(1) NOT NULL DEFAULT '0',
`userid` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `astatus` (`astatus`),
KEY `userid` (`userid`),
KEY `sender` (`sender`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=22975 ;

J'ai même essayé le texte intégral pour sender mais toujours pas de chance et j'ai aussi essayé d'indexer sur toutes les where clause colonnes.

ALTER TABLE `tblsender` ADD INDEX ( `sender` , `astatus` , `userid` ) ;

Je reçois toujours using where Comment puis-je indexer correctement cette table ?

Edit : Expliquer la sortie pour la structure ci-dessus.

id  select_type table       type    possible_keys           key     key_len     ref     rows    Extra   
1   SIMPLE      tblsender   ref     astatus,userid,sender   astatus     1       const   1       Using where

et la sortie Explain pour les 3 colonnes ensemble

id  select_type table       type    possible_keys                   key     key_len     ref     rows    Extra
1   SIMPLE      tblsender   ref     astatus,userid,sender,sender_2  astatus     1       const   1       Using where

4voto

Michael - sqlbot Points 7058

Vous ne pouvez pas prédire efficacement le comportement de l'optimiseur sur de grands ensembles de données lorsque vous effectuez des tests avec de petits ensembles de données.

Comme le montrent les plans de requête, l'index multi-colonnes est considéré comme un candidat, mais l'optimiseur choisit de ne pas l'utiliser. dans ce cas . Cela ne signifie pas qu'elle ne l'utilisera pas lorsque cela sera considéré comme plus avantageux.

Je ne peux que spéculer sans voir votre ensemble de données réelles et peut-être en utilisant traçage de l'optimiseur mais je vais offrir une spéculation raisonnable.

L'optimiseur de MySQL est basé sur les coûts. Il essaie de résoudre votre requête de la manière la moins coûteuse possible. Notez que rows = 1. Cela signifie que l'optimiseur a conclu que -- statistiquement, au moins -- il s'attend à ce qu'une seule ligne corresponde dans l'index de astatus . Avec key_len = 1, ce qui signifie que astatus n'a qu'un seul octet de largeur -- contrairement à l'index multicolonne, qui a une largeur de 11 octets (1 + 6 + 4) -- l'indice astatus semble être une solution très peu coûteuse, et il décide donc d'opter pour cet indice. L'utilisation de l'index le plus long signifie théoriquement plus d'E/S, donc plus coûteux, bien que dans ce cas (en raison d'un petit ensemble de données), les humains reconnaissent que la différence de coût n'est pas particulièrement significative.

Using where signifie que pour chaque ligne effectivement renvoyée en utilisant cet index, le serveur devra vérifier que les lignes correspondent au reste de l'index WHERE mais si nous ne nous attendons à ce qu'environ une ligne corresponde, ce n'est pas un problème.

Je suggère donc que vous n'avez pas de raison de vous inquiéter, car la petite taille de l'ensemble de données actuel ne pourra pas vous donner des informations utiles pour prédire le comportement futur. Dans ce cas précis, Using where est un artefact du petit nombre de lignes dans le tableau.

Vous avez besoin de plus de données. Mais oui, vous voulez un index multicolonne ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X