Question

I have four tables (but I'll query only three of them):

Articles (article is an 'item', type 6): *a_id, a_title, a_text*

Keywords (if a keyword is for articles, its type is 6): *kw_id, kw_type*

Keywords_Translation *kw_id, language_id, kw_name*

Conn_Item_Keyword (many-to-many connection table between items and keywords): *kw_id, kw_type, item_id*

Let's say that I want to query all the keywords of an article with ID 15 and in English (language_id = 1).

I could write this:

SELECT * FROM Conn_Item_Keyword c
LEFT JOIN Keywords k ON (c.kw_id = k.kw_id)
LEFT JOIN Keywords_Translation tr ON (c.kw_id = tr.kw_id)
WHERE c.kw_type = 6 AND c.item_id = 15 AND tr.language_id = 1

But it seems to me very slow, since it joins the Keywords to all the rows of Conn_Item_Keyword. I tried multiple conditions in joins (c.kw_id = k.kw_id AND c.kw_type = 6 AND c.item_id = 15), but I couldn't figure it out correctly.

What's the best way to write this query?

Was it helpful?

Solution

1) Replace the "SELECT *" with "SELECT col1, col2, expr3, ..." so that the query is returning only the expressions you need, and referencing only the needed columns in the SELECT list

2) Get the output from EXPLAIN

3) Make sure you have suitable indexes that can be used, and that they are being used (covering indexes where appropriate)

I don't really see anything horribly wrong in your statement, but I do notice that the join to tr is not really an OUTER join, because of the tr.language_id = 1 predicate in the WHERE clause. You may not need the join to k to be an OUTER join, or you may not need the join to k at all. (But I'm not clear on what result set you want returned.)

What's "wrong" with the result set returned by this query (too many rows? some rows missing? need additional columns?

SELECT c.kw_id
     , tr.kw_name
  FROM Conn_Item_Keyword c
  JOIN Keywords_Translation tr ON tr.kw_id = c.kw_id AND tr.language_id = 1
 WHERE c.kw_type = 6
   AND c.item_id = 15

If you need the join to the Keywords table, then

SELECT c.kw_id
     , tr.kw_name
  FROM Conn_Item_Keyword c
  JOIN Keywords_Translation tr ON tr.kw_id = c.kw_id AND tr.language_id = 1
  JOIN Keywords k ON k.kw_id = c.kw_id
 WHERE c.kw_type = 6
   AND c.item_id = 15

For performance, verify you have indexes such as:

Conn_Item_Keyword (item_id,kw_type,kw_id)
Keywords_Translation (kw_id,language_id)
Keywords(kw_id,kw_name)

Look at the output from EXPLAIN to see whether indexes are being used.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top