【问题标题】:What's the most optimised MySQL query for these three tables?这三个表最优化的 MySQL 查询是什么?
【发布时间】:2012-08-30 16:03:53
【问题描述】:

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

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

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

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

Conn_Item_Keyword(物品与关键字之间的多对多连接表): *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),但我无法正确计算出来。

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

【问题讨论】:

  • “最优化”。 “最好的”。取决于许多其他因素:每个表中的记录数、定义的索引、存储引擎、MySQL 配置参数...
  • 使用EXPLAIN your_query 了解有关 MySQL 如何执行查询的更多信息。

标签: mysql join query-optimization multi-table


【解决方案1】:

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

2) 从 EXPLAIN 中获取输出

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

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

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

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-03-20
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多