2010-05-25 7 views
3

J'ai 2 tables de projet et Projectlist comme celui-ciproblème de requête SQL

Projet

ProjectID 
Name 
ProjectListID - allow null 

Dans Projectlist

ProjectListID 
ProjName 

Maintenant, ce que je dois ici, je veux que les recoed de la table Projectlist ProjectListID pas dans la table de projet. J'ai fait une requête, mais il faut beaucoup de temps pour l'exécuter.

select * FROM projectslist pl where pl.ProjectsListID not in (SELECT p.ProjectsListID FROM project p where (p.ProjectsListID is not null and p.ProjectsListID <>0)) 

S'il vous plaît aidez-moi à créer une requête optimiser. J'utilise Mon SQL.

+0

Est-ce que 'p.ProjectsListID' peut être annulé? – Quassnoi

+0

yes son nullable dans le projet – Pankaj

+0

Avez-vous une colonne non-nullable dans 'projects'? – Quassnoi

Répondre

1

NOT NULL état dans votre requête est redondante: <> 0 implique qu'il:

SELECT * 
FROM projectslist pl 
WHERE pl.ProjectsListID NOT IN 
     (
     SELECT p.ProjectsListID 
     FROM project p 
     WHERE p.ProjectsListID <> 0 
     ) 

Pour que cela fonctionne rapidement, vous devez créer un index sur project (ProjectsListID).

Pourriez-vous s'il vous plaît lancer

EXPLAIN 
SELECT * 
FROM projectslist pl 
WHERE pl.ProjectsListID NOT IN 
     (
     SELECT p.ProjectsListID 
     FROM project p 
     WHERE p.ProjectsListID <> 0 
     ) 

et après sa sortie ici?

Mise à jour:

Depuis la colonne en question est annulable, il est préférable de réécrire la requête comme NOT EXISTS:

SELECT * 
FROM projectslist pl 
WHERE NOT EXISTS 
     (
     SELECT NULL 
     FROM project p 
     WHERE p.ProjectsListID = pl.ProjectsListID 
       AND p.ProjectsListID <> 0 
     ) 
+0

1, 'PRIMARY', 'pl', 'ALL', '', '', '', '', 3827, 'Utiliser où' – Pankaj

+0

2, 'SUBPERY DEPENDANT', 'p', 'ALL', ' ',' ',' ',' ', 1459,' Utiliser où ' – Pankaj

+0

@Pankaj: pourriez-vous s'il vous plaît créer l'index et voir si le plan de requête change? – Quassnoi

2

ProjectList.ProjectListID est autorise pas droit nul?

alors vous devriez essayer de comparer en utilisant GAUCHE REJOINT:

SELECT * FROM ProjectList pl LEFT JOIN Project p ON pl.ProjectListID = p.ProjectListID 
WHERE pl.ProjectListID is null 
+0

Ou légèrement plus concis: SELECT * FROM ProjectList LEFT JOIN PROJECT UTILISER (ProjectListID) WHERE ProjectList.ProjectListID IS NULL – ChrisV

+0

Cela ne retournera jamais rien. – Quassnoi

0
select project_list.* 
from project_list left join project using (project_list_id) 
where isnull(project.project_id) 

Cette requête est beaucoup plus rapide que les solutions fournies par d'autres utilisateurs sous-requête.

+0

Cette requête serait plus lente si 'project' est' MyISAM' et qu'il n'y a pas d'index composite sur '(project_list_id, project_id)'. En général, 'LEFT JOIN/IS NULL' et' NOT IN' fonctionnent aussi bien dans 'MySQL': http: // explainextended.com/2009/09/18/pas-dans-vs-n'existe-vs-gauche-join-est-null-mysql/ – Quassnoi

+1

bien la première étape dans l'optimisation de la requête est l'optimisation de schéma, ce qui implique la création d'index pertinents :) Je présume qu'une colonne est utilisée pour filtrer les résultats, donc la plupart du temps ça devrait faire partie de la clé :) –