0

I have a query with joins that is not using the index that would be the best match and I am looking for help to correct this.

I have the following query:

select
equipment.name,purchaselines.description,contacts.name,vendors.accountNumber
from purchaselines
left join vendors on vendors.id = purchaselines.vendorId
left join contacts on contacts.id = vendors.contactId
left join equipment on equipment.id = purchaselines.equipmentId
where contacts.id = 12345

The table purchaselines has an index on the column vendorId, which is the proper index to use. When the query is run, I know the value of contacts.id which is joined to vendors.contactId which is joined to purchaselines.vendorId.

What is the proper way to run this query? Currently, no index is used on the table purchaselines.

1 Answer 1

1

If you are intending to query a specific contact, I would put THAT first since that is the primary basis. Additionally, you had left-joins to the other tables (vendors, contacts, equipment). So by having a WHERE clause to the CONTACTS table forces the equation to become an INNER JOIN, thus REQUIRING.

That said, I would try to rewrite the query as (also using aliases for simplified readability of longer table names)

select
      equipment.name,
      purchaselines.description,
      contacts.name,
      vendors.accountNumber
   from 
      contacts c
         join vendors v
            on c.id = v.contactid
            join purchaselines pl
               on v.id = pl.vendorid
               join equipment e
                  on pl.equipmentid = e.id
   where
      c.id = 12345

Also notice the indentation of the JOINs helps readability (IMO) to see how/where each table gets to the next in a more hierarchical manner. They are all regular inner JOIN context.

So, the customer ID will be the first / fastest, then to vendors by that contact ID which should optimize the join to that. Then, I would expect the purchase lines to have an index on vendorid optimizing that. And finally, the equipment table on ITs PK.

FEEDBACK Basic JOIN clarification.

JOIN is just the explicit statement of how two tables are related. By listing them left-side and right-side and the join condition showing on what relationship is between them is all.

Now, in your data example, each table is subsequently nested under the one prior. It is quite common though that one table may link to multiple other tables. For example an employee. A customer could have an ethnicity ID linking to an ethnicity lookup table, but also, a job position id also linking to a job position lookup table. That might look something like

select
      e.name,
      eth.ethnicity,
      jp.jobPosition
   from
      employee e
         join ethnicitiy eth
            on e.ethnicityid = eth.id
         join jobPosition jp
            on e.jobPositionID = jp.id

Notice here that both ethnicity and jobPosition are at the same hierarchical level to the employee table scenario. If, for example, you wanted to further apply conditions that you only wanted certain types of employees, you can just add your logical additional conditions directly at the location of the join such as

     join jobPosition jp
        on e.jobPositionID = jp.id
        AND jp.jobPosition = 'Manager'

This would get you a list of only those employees who are managers. You do not need to explictily add a WHERE condition if you already include it directly at the JOIN/ON criteria. This helps keeping the table-specific criteria at the join if you ever find yourself needing LEFT JOINs.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I need to work on my understanding of joins.
@user3720435, see updated answer to help clarify JOINs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.