tags:

views:

68

answers:

3
+3  Q: 

SQL query problem

Hello All

I have 2 tables Project and ProjectList like this

Project

ProjectID
Name
ProjectListID - allow null

In ProjectList

ProjectListID
ProjName

Now what i need here, i want only those recoed from ProjectList table which ProjectListID not in Project table. I made a query but it is taking lot of time to execute.

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))

Please help me to create optimize query. I am using My SQL.

+1  A: 

NOT NULL condition in your query is redundant: <> 0 implies it:

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

For this to work fast, you need to create an index on project (ProjectsListID).

Could you please run

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

and post its output here?

Update:

Since the column in question is nullable, it is better to rewrite the query as NOT EXISTS:

SELECT  *
FROM    projectslist pl
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    project p
        WHERE   p.ProjectsListID = pl.ProjectsListID
                AND p.ProjectsListID <> 0
        )
Quassnoi
1, 'PRIMARY', 'pl', 'ALL', '', '', '', '', 3827, 'Using where'
Pankaj
2, 'DEPENDENT SUBQUERY', 'p', 'ALL', '', '', '', '', 1459, 'Using where'
Pankaj
@Pankaj: could you please create the index and see if the query plan changes?
Quassnoi
Thanks @ Quassnoi..
Pankaj
can we create index on nullable column also? i also created index on project (ProjectsListID).
Pankaj
@Pankaj: of course we can.
Quassnoi
+2  A: 

Hi,

ProjectList.ProjectListID is not allow null right?

then you should try to compare by using LEFT JOINS:

SELECT * FROM ProjectList pl LEFT JOIN Project p ON pl.ProjectListID = p.ProjectListID
WHERE pl.ProjectListID is null
Christofel
Or slightly more concise: SELECT * FROM ProjectList LEFT JOIN PROJECT USING (ProjectListID) WHERE ProjectList.ProjectListID IS NULL
ChrisV
This will never return anything.
Quassnoi
A: 
select project_list.*
from project_list left join project using (project_list_id)
where isnull(project.project_id)

This query is much faster than the solutions provided by others using subquery.

ovais.tariq
This query would be slower if `project` is `MyISAM` and there is no composite index on `(project_list_id, project_id)`. In general, `LEFT JOIN / IS NULL` and `NOT IN` perform equally well in `MySQL`: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/
Quassnoi
well the first step in query optimization is schema optimization, which involves creating relevant indexes :) so i presume since a column is being used to filter results so most of the times it should be a part of the key :)
ovais.tariq