2010-10-04 5 views
1

donc j'ai commencé avec cette requête:MySQL Je veux optimiser cet autre

SELECT * FROM TABLE1 WHERE hash IN (SELECT id FROM temptable); 

Il a fallu pour toujours, alors j'ai couru une expliquer:

mysql> explain SELECT * FROM TABLE1 WHERE hash IN (SELECT id FROM temptable); 
+----+--------------------+-----------------+------+---------------+------+---------+------+------------+-------------+ 
| id | select_type  | table   | type | possible_keys | key | key_len | ref | rows  | Extra  | 
+----+--------------------+-----------------+------+---------------+------+---------+------+------------+-------------+ 
| 1 | PRIMARY   | TABLE1   | ALL | NULL   | NULL | NULL | NULL | 2554388553 | Using where | 
| 2 | DEPENDENT SUBQUERY | temptable  | ALL | NULL   | NULL | NULL | NULL |  1506 | Using where | 
+----+--------------------+-----------------+------+---------------+------+---------+------+------------+-------------+ 
2 rows in set (0.01 sec) 

Il n'a pas utilisé un index. Donc, mon deuxième passage:

mysql> explain SELECT * FROM TABLE1 JOIN temptable ON TABLE1.hash=temptable.hash; 
+----+-------------+-----------------+------+---------------+----------+---------+------------------------+------+-------------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref     | rows | Extra  | 
+----+-------------+-----------------+------+---------------+----------+---------+------------------------+------+-------------+ 
| 1 | SIMPLE  | temptable  | ALL | hash   | NULL  | NULL | NULL     | 1506 |    | 
| 1 | SIMPLE  | TABLE1   | ref | hash   | hash  | 5  | testdb.temptable.hash | 527 | Using where | 
+----+-------------+-----------------+------+---------------+----------+---------+------------------------+------+-------------+ 
2 rows in set (0.00 sec) 

Puis-je effectuer d'autres optimisations?

+1

Avez-vous vraiment besoin de '' SELECT *? – nico

+0

@nico: +1 pour cela. Merci. – Legend

Répondre

1

Vous pouvez gagner un peu plus de vitesse en utilisant un covering index, au coût de la consommation d'espace supplémentaire. Un index de couverture est celui qui peut satisfaire toutes les colonnes demandées dans une requête sans effectuer de recherche supplémentaire dans l'index clusterisé.

d'abord se débarrasser de la SELECT * et sélectionner explicitement les champs dont vous avez besoin. Vous pouvez ensuite ajouter tous les champs de la clause SELECT à droite de votre index composite. Par exemple, si votre requête ressemblera à ceci:

SELECT first_name, last_name, age 
FROM table1 
JOIN temptable ON table1.hash = temptable.hash; 

Ensuite, vous pouvez avoir un indice de couverture qui ressemble à ceci:

CREATE INDEX ix_index ON table1 (hash, first_name, last_name, age); 
+0

Je vais supprimer le *. Une question rapide: Si l'espace n'est pas vraiment un problème, est-il logique d'ajouter un index sur toutes les colonnes? – Legend

+0

@Legend: Oui, dans de nombreuses situations, il est recommandé. En général, le principal inconvénient d'un index couvrant sur un index régulier est qu'il prend beaucoup plus d'espace, et que les insertions et les mises à jour deviennent un peu plus lentes (ou prennent plus de ressources). À moins d'insérer de nombreux nouveaux enregistrements par seconde, cela est rarement un problème et est souvent négligeable. –

+0

Merci. Je vais essayer cela et voir si cela fonctionne. Ma table a 2 milliards d'enregistrements mais je ne les mettrai plus à jour. – Legend

Questions connexes