2013-02-18 4 views
2

J'ai une table principale et une table enfant avec une clé étrangère. Quand je joins entre ces deux tableaux et utiliser EXPLAIN pour analyser les performancesClés étrangères d'optimisation de requête Mysql

  1. Je reçois le EXPLAIN comme « type = ALL » qui est considéré comme le pire pour la performance. Comment puis-je améliorer les performances de cette jointure?

  2. expliquer la sortie montre que "possible_keys: cid_index" au lieu de clé et keylength

Voici un test

CREATE TABLE `master` (
    `mid` bigint(20) NOT NULL AUTO_INCREMENT, 
    `mname` varchar(20) NOT NULL, 
    PRIMARY KEY (`mid`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 


select * from master; 
+-----+-------+ 
| mid | mname | 
+-----+-------+ 
| 1 | one | 
| 2 | two | 
+-----+-------+ 
2 rows in set (0.25 sec) 


CREATE TABLE `child` (
    `cid` bigint(20) NOT NULL AUTO_INCREMENT, 
    `cname` varchar(10) NOT NULL, 
    `Ccid` bigint(20) DEFAULT NULL, 
    PRIMARY KEY (`cid`), 
    KEY `cid_index` (`Ccid`), 
    CONSTRAINT `new_fk_constraint` FOREIGN KEY (`Ccid`) REFERENCES `master` (`mid`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 



select * from child; 
+-----+-------+------+ 
| cid | cname | Ccid | 
+-----+-------+------+ 
| 1 | Cone | 1 | 
| 2 | ctwo | 2 | 
+-----+-------+------+ 
2 rows in set (0.12 sec) 



explain select m.*,c.* from master m join child c on m.mid=c.Ccid \G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: m 
     type: ALL 
possible_keys: PRIMARY 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 2 
     Extra: 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: ALL 
possible_keys: cid_index 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 2 
     Extra: Using where; Using join buffer 
2 rows in set (0.23 sec) 
+0

Combien de lignes de données avez-vous dans le tableau? De votre exemple, il semble que 4 lignes? L'utilisation d'un index n'est pas efficace car une analyse de table peut être effectuée plus rapidement avec de si petites quantités de données. Rappelez-vous qu'un plan d'exécution de requête va changer au fil du temps. – Namphibian

+0

'JOIN' est un produit cartésien, donc utiliser des index est inutile? – SparKot

+0

J'ai augmenté le nombre d'enregistrements à 10 dans chaque. Maintenant, MySQL utilise des index pour les comparaisons. Doit être l'une de ces astuces 'Query Optimisation', pesant les frais généraux. – SparKot

Répondre

3

Si la table est trop petite, avec pas grand-chose à filtrer , la performance pourrait ne pas être comme prévu. Habituellement, si la clause where filtre plus de x% (environ 30%), l'analyse de la table entière sera plus efficace. S'il vous plaît vérifier la On mysql performance

Vous pouvez également essayer de forcer l'index et vérifier si l'indice est utilisé

explain select m.*,c.* 
from master m 
join child c force index(Ccid) 
on m.mid=c.Ccid