简体   繁体   English

这三个表中最优化的MySQL查询是什么?

[英]What's the most optimised MySQL query for these three tables?

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* 文章 (文章是“项目”,类型6):* a_id,a_title,a_text *

Keywords (if a keyword is for articles, its type is 6): *kw_id, kw_type* 关键字 (如果关键字是用于文章的关键字,则其类型为6):* kw_id,kw_type *

Keywords_Translation *kw_id, language_id, kw_name* 关键字翻译 * kw_id,language_id,kw_name *

Conn_Item_Keyword (many-to-many connection table between items and keywords): *kw_id, kw_type, item_id* Conn_Item_Keyword (项目与关键字之间的多对多连接表):* 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). 假设我要查询ID为15且为英文(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. 但是在我看来,这很慢,因为它将关键字连接到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. 我在联接中尝试了多个条件(c.kw_id = k.kw_id AND c.kw_type = 6 AND c.item_id = 15),但我无法正确找出。

What's the best way to write this query? 编写此查询的最佳方法是什么?

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 1)将“ SELECT * ”替换为“ SELECT * SELECT col1, col2, expr3, ... ”,以便查询仅返回所需的表达式,并且仅引用SELECT列表中所需的列

2) Get the output from EXPLAIN 2)从EXPLAIN获取输出

3) Make sure you have suitable indexes that can be used, and that they are being used (covering indexes where appropriate) 3)确保您拥有可以使用的合适索引,并且正在使用它们(在适当的地方覆盖索引)

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. 在您的陈述中,我确实没有看到任何可怕的错误,但是我确实注意到,由于WHERE子句中的tr.language_id = 1谓词,因此对trtr.language_id = 1并不是真正的OUTER tr.language_id = 1 You may not need the join to k to be an OUTER join, or you may not need the join to k at all. 您可能不需要将与k连接成为外部连接,或者根本不需要与k的连接。 (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. 查看EXPLAIN的输出以查看是否正在使用索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM