Requête MySQL n'utilise pas l'index dans la table de jointure
Je suis en train de la liste de tous les book_sales de l'information pour un particulier de l'auteur du livre. J'ai donc une requête et il n'est pas à l'aide d'Index pour la recherche de documents.
Ce qui suit est mon de la structure des tables:
-- Table structure for table `books`
CREATE TABLE IF NOT EXISTS `books` (
`book_id` int(11) NOT NULL auto_increment,
`author_id` int(11) unsigned NOT NULL,
`book_type_id` int(11) NOT NULL,
`book_title` varchar(50) NOT NULL,
`book_price` smallint(4) NOT NULL,
`in_stock` char(1) NOT NULL,
PRIMARY KEY (`book_id`),
KEY `book_type_id` (`book_type_id`),
KEY `author_id` (`author_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-- Dumping data for table `books`
INSERT INTO `books` (`book_id`, `author_id`, `book_type_id`, `book_title`, `book_price`, `in_stock`) VALUES
(1, 1, 1, 'My Book 1', 10, 'y'),
(2, 2, 1, 'My Book 2', 20, 'n'),
(3, 1, 2, 'My Book 3', 30, 'y'),
(4, 3, 3, 'My Book 4', 40, 'y'),
(5, 4, 2, 'My Book 5', 50, 'n'),
(6, 1, 1, 'My Book 6', 60, 'y'),
(7, 5, 3, 'My Book 7', 70, 'n'),
(8, 6, 2, 'My Book 8', 80, 'n'),
(9, 7, 1, 'My Book 9', 90, 'y'),
(10, 8, 3, 'My Book 10', 100, 'n');
-- Table structure for table `book_sales`
CREATE TABLE IF NOT EXISTS `book_sales` (
`sale_id` int(11) NOT NULL auto_increment,
`book_id` int(11) NOT NULL,
`sale_amount` decimal(8,2) NOT NULL default '0.00',
`time` datetime NOT NULL default '0000-00-00 00:00:00',
`price` smallint(8) NOT NULL,
PRIMARY KEY (`sale_id`),
KEY `book_id` (`book_id`),
KEY `price` (`price`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
-- Dumping data for table `book_sales`
INSERT INTO `book_sales` (`sale_id`, `book_id`, `sale_amount`, `time`, `price`) VALUES
(1, 1, '10.00', '2010-02-23 10:00:00', 20),
(2, 1, '20.00', '2010-02-24 11:00:00', 20);
Ma Requête:
SELECT sale_amount, price
FROM book_sales
INNER JOIN books ON book_sales.book_id = books.book_id
WHERE books.author_id =1
L'EXPLIQUER ci-dessus, montre-moi:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE books ref PRIMARY,author_id author_id 4 const 3 Using index
1 SIMPLE book_sales ALL book_id NULL NULL NULL 2 Using where
Clairement, book_sales n'est pas à l'aide de la touche 'book_id', bien que je l'ai. Que puis-je faire pour faire de la book_sales l'utilisation de la table de l'Index?
Merci.
Modifications effectuées sur la base de propositions (mais le résultat est qu'ils n'utilisent pas encore l'index):
//Does not use the index in book_sales table
EXPLAIN SELECT sale_amount, price
FROM books, book_sales
FORCE INDEX ( book_id )
WHERE book_sales.book_id = books.book_id
AND books.author_id =1
//Does not use the index in book_sales table
EXPLAIN SELECT sale_amount, price
FROM book_sales, books
WHERE books.author_id = 1
AND book_sales.book_id = books.book_id
Comment faire pour forcer la book_sale table avec seulement 2 lignes, utiliser l'index ? Merci.
OriginalL'auteur Devner | 2010-02-25
Vous devez vous connecter pour publier un commentaire.
Comme vous pouvez le voir dans l'EXPLIQUER, "book_id" est répertorié comme une clé possible. Si MySQL ne l'utilise pas, c'est juste que l'optimiseur ne pense pas qu'il permettrait d'accélérer la requête. Ce qui est vrai si "book_sales" a seulement 2 lignes, et 100% de ces lignes partagent les mêmes "book_id". Cela s'appelle de la cardinalité de la tva. Comment Éviter les Analyses de la Table (Manuel MySQL)
Essayer de le remplir avec plus de lignes et vous devriez voir que MySQL va utiliser un index pour la rejoindre.
Edit: la requête
...ne fonctionne pas, soit, dans ce cas, car l'optimiseur toujours reconnaît que la lecture de l'index n'est pas optimale et les commutateurs de la table afin d'éviter de le faire. Vous pouvez forcer l'ordre de la table en utilisant STRAIGHT_JOIN. C'est, cependant, un peu un hack, parce qu'il oblige MySQL pour exécuter la requête d'une manière qui n'est pas le meilleur.
+1 c'est vrai et valable dans tous les cas.
Davis Merci pour la réponse. Comme vous l'avez suggéré, j'ai rempli le tableau avec les données supplémentaires et quand j'ai essayé la requête que j'avais avec moi d'abord, il a travaillé! Le book_sales table a l'aide de la book_id clé!!! Soulagement, enfin!!! Voici donc le coupable a été mysql slow query log. J'ai eu il allumé et a été la journalisation de toutes les requêtes qui n'étaient pas à l'aide de l'index et cette requête a montré dans le journal et ma bataille a commencé avec elle. Donc est il possible que je peux supprimer ce journal de montrer les requêtes au dessus de la nature? Merci beaucoup!
Autant que je sache, vous ne pouvez pas filtrer les requêtes aller à la slow query log, mais vous devriez être en mesure de forcer l'optimiseur pour éviter que la table d'analyse en utilisant l'INDICE de FORCE. dev.mysql.com/doc/refman/5.5/en/index-hints.html
Davis, j'ai renvoyé le lien que vous avez posté et je pensais que je serais en mesure de Forcer l'index à être utilisé, et obtenir ma requête comme souhaité, mais il ne fonctionne toujours pas et que la table n'utilise pas l'index. En tant que tel, j'ai édité mon premier post pour y inclure les requêtes que j'ai essayé. Peut-être que si je fais quelque chose de mal, merci de me suggérer applicables correction. Je vous remercie.
OriginalL'auteur Josh Davis
Essayer cette
Hy Devner Veuillez suivre la réponse de Josh Davis
Je l'ai fait et j'ai visité le lien qu'il a posté. Je vois une option appelée "--max-cherche-pour-key=1000". Il dit: "Démarrer mysqld avec l'option --max-cherche-pour-key=1000 ou l'option d'utiliser un ENSEMBLE max_seeks_for_key=1000 à dire l'optimiseur de supposer qu'aucune clé d'analyse des causes de plus de 1 000 clés cherche." Je ne suis pas sûr de ce que cela signifie vraiment. Pouvez-vous s'il vous plaît jeter toute la lumière sur cette? Je vous remercie.
OriginalL'auteur streetparade