0

我有四个表(但我只会查询其中三个):

文章(文章是“项目”,类型 6):*a_id、a_title、a_text*

关键字(如果关键字是文章,则其类型为 6):*kw_id, kw_type*

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

conn_Item_Keyword(item和keywords之间的多对多连接表):*kw_id, kw_type, item_id*

假设我要查询一篇 ID 为 15 的英文文章的所有关键词(language_id = 1)。

我可以这样写:

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

但在我看来它很慢,因为它将关键字连接到 Conn_Item_Keyword 的所有行。我在连接中尝试了多个条件(c.kw_id = k.kw_id AND c.kw_type = 6 AND c.item_id = 15),但我无法正确理解。

编写此查询的最佳方法是什么?

4

1 回答 1

0

1) 将“ SELECT *”替换为“”,SELECT col1, col2, expr3, ...以便查询仅返回您需要的表达式,并仅引用 SELECT 列表中所需的列

2) 从 EXPLAIN 获取输出

3)确保您有合适的索引可以使用,并且它们正在被使用(在适当的情况下覆盖索引)

我真的没有在您的陈述中看到任何可怕的错误,但我注意到由于子句中的谓词, join totr并不是真正的 OUTER join 。您可能不需要加入成为 OUTER 加入,或者您可能根本不需要加入。(但我不清楚你想要返回什么结果集。)tr.language_id = 1WHEREkk

此查询返回的结果集有什么“错误”(行太多?缺少某些行?需要额外的列?

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

如果您需要连接到关键字表,那么

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

为了提高性能,请验证您是否具有以下索引:

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

查看 EXPLAIN 的输出以查看是否正在使用索引。

于 2012-08-30T18:22:15.547 回答