Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / Databases / October 2004

Tip: Looking for answers? Try searching our database.

Inner Join / Indexes Hell

Thread view: 
Ike - 14 Oct 2004 13:52 GMT
Oh I have a nasty query which runs incredibly slowly. I am running MySQL
4.0.20-standard. Thus, in trying to expedite the query, I am trying to set
indexes in my tables.
My query requires four inner joins, as follows :

SELECT DISTINCT
upcards.id,statuskey.status,upcards.firstname,upcards.lastname,originkey.ori
gin,associatekey.username,associatekey2.username,upcards.deleted
FROM upcards,status,origins,associates
INNER JOIN status statuskey on upcards.statuskey=statuskey.id
INNER JOIN origins originkey on upcards.originkey=originkey.id
INNER JOIN associates associatekey on upcards.associatekey=associatekey.id
INNER JOIN associates associatekey2 on
upcards.associatekey2=associatekey2.id
WHERE (upcards.deleted is null OR upcards.deleted = 0) AND
(associatekey.branch IS NULL OR associatekey.branch LIKE '' OR
associatekey.branch LIKE '%');

The tables structure is:

table upcards
id
firstname
lastname
deleted
statuskey
originkey
associatekey
associatekey2

table status
id
status

table origins
id
origins

table associates
id
username
branch

Thus, to expedite my query, I am setting my indexes as follows: (id is a
PRIMARY key on all tables)
for the table upcards I set as indexes:
deleted
statuskey
originkey
associatekey
associatekey2

and for associates:
branch

In doing so, I have every column thus indexed, you would think this query
would run faster, but it does not. Is there a better means of setting my
indexes here to speed up this query? Perhaps there is a more efficient way
to write this query, i.e. perhaps the problem is not so much with my
indexing, as with the query itself? Thanks, Ike
2metre - 14 Oct 2004 15:17 GMT
> SELECT DISTINCT
> upcards.id,statuskey.status,upcards.firstname,upcards.lastname,originkey.ori
[quoted text clipped - 5 lines]
> INNER JOIN associates associatekey2 on
> upcards.associatekey2=associatekey2.id ...

1/ I would recommend using different aliases. Isnt the whole point of
aliases to reduce the amount of code to type and make the query easier
to read? Not only are your aliases longer than the original tablenames
but they're also confusing because they duplicate the names of fields!
How about using a and a2?

> WHERE (upcards.deleted is null OR upcards.deleted = 0) AND
> (associatekey.branch IS NULL OR associatekey.branch LIKE '' OR
> associatekey.branch LIKE '%');

2/ What other value could associatekey.branch take? You seem to have
matched on null, empty and any value?

3/ Your 'from' clause is replicating tables that are already joined
within your INNER JOIN statements.
Ike - 14 Oct 2004 16:30 GMT
Ah.....when I take your point #3 into account, below....things run
beautifully. //Ike

> > SELECT DISTINCT

upcards.id,statuskey.status,upcards.firstname,upcards.lastname,originkey.ori
> > gin,associatekey.username,associatekey2.username,upcards.deleted
> > FROM upcards,status,origins,associates
[quoted text clipped - 19 lines]
> 3/ Your 'from' clause is replicating tables that are already joined
> within your INNER JOIN statements.
justaguy - 16 Oct 2004 22:47 GMT
>>> SELECT DISTINCT upcards.id, statuskey.status,
>>>   upcards.firstname, upcards.lastname, originkey.origin,
[quoted text clipped - 8 lines]
>>>     on upcards.associatekey2 = associatekey2.id
>>> ...

"2metre" wrote:
>> ...
>> 3/ Your 'from' clause is replicating tables that are already joined
>> within your INNER JOIN statements.

> Ah.....when I take your point #3 into account, ...
> things run beautifully. //Ike

But, of course!  The FROM clause with four tables listed makes a cross
join of all four, which itself is then joined with each of the other
four views.  This is huge and slow.

Changing the FROM ... JOIN ... clauses to what you really meant
eliminates the cross product, simplifies the query and speeds it up
geometrically.

SELECT DISTINCT upcards.id, status.status,
   upcards.firstname, upcards.lastname, origins.origin,
   associates.username, a2.username, upcards.deleted
 FROM upcards
  INNER JOIN status on upcards.statuskey = status.id
  INNER JOIN origins on upcards.originkey = origins.id
  INNER JOIN associates on upcards.associatekey = associates.id
  INNER JOIN associates a2 on upcards.associatekey2 = a2.id
;

Others have addressed the logic of table aliases.

A google on SQL CROSS JOIN found, for example,
http://www.sql-server-performance.com/tuning_joins.asp

excerpt:
... I ran across a slow-performing query from an ERP program. ... I
noticed that instead of creating a LEFT JOIN, the developer had
accidentally created a CROSS JOIN instead. In this particular example,
less than 10,000 rows should have resulted from the LEFT JOIN, but
because a CROSS JOIN was used, over 11 million rows were returned
instead. Then the developer used a SELECT DISTINCT to get rid of all the
unnecessary rows created by the CROSS JOIN. As you can guess, this made
for a very lengthy query.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.