【问题标题】:SQL Join condition optimizationSQL Join 条件优化
【发布时间】:2014-01-05 00:07:43
【问题描述】:

我遇到了一个缓慢的 SQL 查询问题,导致我转到 500 Internal Server Error

在对查询进行了一些操作后,我发现将连接条件移到外部可以使查询正常工作并且错误消失。

现在我想知道:

  • 第二个查询是否等同于第一个?
  • 我的错误是什么,为什么这么慢?

这里是查询。

原始(慢)SQL:

SELECT *
FROM `TABLE_1` AS `main_table`
  INNER JOIN `TABLE_2` AS `w`
    ON main_table.entity_id = w.product_id
  LEFT JOIN `TABLE_3` AS `ur`
    ON main_table.entity_id = ur.product_id 
       AND ur.category_id IS NULL 
       AND ur.store_id = 1 
       AND ur.is_system = 1
WHERE (w.website_id = '1')

更快的 SQL:

SELECT *
FROM `TABLE_1` AS `main_table`
  INNER JOIN `TABLE_2` AS `w`
    ON main_table.entity_id = w.product_id
  LEFT JOIN `TABLE_3` AS `ur`
    ON main_table.entity_id = ur.product_id 
WHERE (w.website_id = '1') 
AND ur.category_id IS NULL 
AND ur.store_id = 1 
AND ur.is_system = 1

【问题讨论】:

  • 看看以下内容:StackOverflow ;如果结果在 where 子句中被过滤,那么它们已经被排除在 Join 之外。
  • 希望这篇文章对你有所帮助stackoverflow.com/questions/2509987/…
  • 您的第二个查询依赖于在从 TABLE_3 连接之后具有非空值。因此,这实际上是针对 TABLE_3 执行和 INNER JOIN 的。例如,如果前 2 个表有 100 万行匹配,而第 3 个表只有 1 行,那么在您的第一个查询中,您将带回 1m 行,但第二个只会带回 1 行。

标签: mysql sql join query-optimization


【解决方案1】:

第二个查询是否等同于第一个?

根据 TABLE_3 中的数据,第二个查询不等于第一个查询,因为您使用的是 LEFT JOIN

考虑当您在 TABLE_1 中有一条记录,其 entity_id 与 TABLE_3 中的任何行都不匹配时会发生什么:您的第一个查询仍会从 TABLE_1 返回此记录,并且 TABLE_3 的所有列的值为 NULL。第二个查询将过滤器应用于 TABLE_3 中的列,但由于这些都是 NULL,因此现在将过滤掉记录。

一般而言,查询 2 会因此返回比查询 1 更少的记录(当然,除非您的所有 entity_id 都与 TABLE_3 中的 product_id 匹配)。

我的错误是什么,为什么这么慢?

这两个查询都是有效的 SQL,因此它们都不应该给您 500 Internal Server Error。这甚至看起来不像是 MySQL 错误,所以这个 bug 可能出现在其他地方?也许您的 Web 应用程序无法处理从第一个查询返回的 NULL?如果没有有关错误的更多详细信息,就不可能回答这个问题。

至于查询的速度,这在很大程度上取决于定义了哪些索引。一般来说,我不希望第二个查询比第一个快,但这取决于。正如我上面提到的,第一个查询可能会返回比第二个更多的记录。如果您不是直接查询数据库,而是通过某个应用程序查询,会不会是应用程序减慢了您的查询速度?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 2014-11-25
    • 1970-01-01
    相关资源
    最近更新 更多