Reputation: 811
First of all i have the following table structures.
Table Document
## DocID ## ## DocName## ## DuplicateID ##
1 Doc1 null
2 Doc2 null
3 Doc3 null
4 Doc4 1
Table FolderTree
## FolderID ## ## MemberDocID ##
1 1
1 2
1 3
I have index on DocID, DuplicateID and MemberDocID and FolderID
My Query is this :
SELECT d.*
from Document d, FolderTree f
WHERE (d.DocID = f.MemberDocID or d.DuplicateID = f.MemberDocID) and f.FolderID = 1
GROUP BY d.DocID ;
So basically i want to retrieve all documents from Folder with id 1 and also its duplicate documents from the table. The group by is used to maintain uniqueness of record that no document will be retrieve twice.
This query is working fine but in large volume of records it getting slower.Here is the explain output.
| select type | table | type | possible_keys | key | rows | extra |
simple d range PRIMARY,... PRIMARY 83168 Using temporary..
simple f All DuplicateIDInx Null 108787 Using join buffer
What concerns me is that the table f does not use the index on DuplicateID. My question is, Why is it so? Can somebody enlighten me on this matter. Im using Mysql 5.x Thanks :)
Upvotes: 3
Views: 617
Reputation: 74018
You can use an in clause instead and use distinct instead of group by.
SELECT distinct d.*
from Document d
join FolderTree f on f.MemberDocID in (d.DocID, d.DuplicateID)
WHERE f.FolderID = 1
According to SQL Fiddle, this hasn't changed much, besides making the join explicit.
If you change your duplicateid
, however
update document
set duplicateid = docid
where duplicateid is null
and select on duplicateid
only
SELECT distinct d.*
from Document d
join FolderTree f on f.MemberDocID = d.DuplicateID
WHERE f.FolderID = 1
will use the index on duplicateid
Upvotes: 1
Reputation: 115520
Try this version:
SELECT d.*
FROM Document d
WHERE EXISTS
( SELECT *
FROM FolderTree f
WHERE ( d.DocID = f.MemberDocID OR d.DuplicateID = f.MemberDocID )
AND f.FolderID = 1
) ;
and this one (edited):
SELECT d.*
FROM ( SELECT 1 AS FolderID
) AS Parameter
CROSS JOIN
Document d
WHERE EXISTS
( SELECT *
FROM FolderTree f
WHERE f.MemberDocID = d.DocID
AND f.FolderID = Parameter.FolderID
)
OR EXISTS
( SELECT *
FROM FolderTree f
WHERE f.MemberDocID = d.DuplicateID
AND f.FolderID = Parameter.FolderID
) ;
I would also add a compound (composite) index on FolderTree (FolderID, MemberDocID)
.
If you haven't already an index on Document (DuplicateID)
, add one as well.
The extra requirement could probably be better solved by writing the query in a stored procedure with a parameter.
Upvotes: 1
Reputation: 556
looks like proper indexes are not there. can you clarify more on the table structure and query.
Upvotes: 1