Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Improve Query Performance with many JOINs

Tags:

I have a query (with the purpose of making a view) which is using a few joins to get each column. Performance degrades quickly (exponentially?) for each set of joins added.

What would be a good approach to make this query faster? Please see comments within the query.

If it helps, this is using the WordPress DB schema.

Here is a screenshot of EXPLAIN enter image description here

PRODUCTS TABLE

+--+----+ |id|name| +--+----+ |1 |test| +--+----+ 

METADATA TABLE

+----------+--------+-----+ |product_id|meta_key|value| +----------+--------+-----+ |1         |price   |9.99 | +----------+--------+-----+ |1         |sku     |ABC  | +----------+--------+-----+ 

TERM_RELATIONSHIPS TABLE

+---------+----------------+ |object_id|term_taxonomy_id| +---------+----------------+ |1        |1               | +---------+----------------+ |1        |2               | +---------+----------------+ 

TERM_TAXONOMY TABLE

+----------------+-------+--------+ |term_taxonomy_id|term_id|taxonomy| +----------------+-------+--------+ |1               |1      |size    | +----------------+-------+--------+ |2               |2      |stock   | +----------------+-------+--------+ 

TERMS TABLE

+-------+-----+ |term_id|name | +-------+-----+ |1      |500mg| +-------+-----+ |2      |10   | +-------+-----+ 

QUERY

SELECT    products.id,   products.name,   price.value AS price,   sku.value AS sku,   size.name AS size FROM products  /* These joins are performing quickly */  INNER JOIN `metadata` AS price ON products.id = price.product_id AND price.meta_key = 'price' INNER JOIN `metadata` AS sku ON products.id = sku.product_id AND sku.meta_key = 'sku'  /* Here's the part that is really slowing it down - I run this chunk about 5 times with different strings to match */  INNER JOIN `term_relationships` AS tr ON products.id = tr.object_id   INNER JOIN `term_taxonomy` AS tt   ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'size'     INNER JOIN `terms` AS size     ON tt.term_id = size.term_id 
like image 984
dloewen Avatar asked Jan 03 '14 18:01

dloewen


People also ask

How do I avoid too many joins in SQL?

Using the Entity Framework Profiler, I've received the suggestion to reduce the number of joins and, instead, perform several separate queries: link. Each join requires the database to perform additional work, and the complexity and cost of the query grows rapidly with each additional join.

Do joins slow down query?

Joins: If your query joins two tables in a way that substantially increases the row count of the result set, your query is likely to be slow. There's an example of this in the subqueries lesson. Aggregations: Combining multiple rows to produce a result requires more computation than simply retrieving those rows.

Can a query have multiple joins?

Multiple joins can be described as a query containing joins of the same or different types used more than once, thus giving them the ability to combine multiple tables. For this article we will first create a database geeks and then create three tables in it and then run our queries on those tables.


1 Answers

Your performance issue is most likely caused by the join with the 'term_taxonomy' table.
All other joins seems to use the primary key (where you probobly have working indexes on).

So my suggestion is to add a compound index on term_taxonomy_id and term_id (or if you must: taxonomy). Like this:

CREATE UNIQUE INDEX idx_term_taxonomy_id_taxonomy ON term_taxonomy( term_taxonomy_id, taxonomy); 

Hope this will help you.

like image 172
carleson Avatar answered Sep 30 '22 02:09

carleson