【问题标题】:large single join queries vs multiple smaller ones大型单连接查询与多个较小的连接查询
【发布时间】:2014-08-31 03:49:29
【问题描述】:

所以我们正在构建这个应用程序,其中数据的检索基于小型模块化查询。所以对于一个产品来说,它会是这样的:

$product = $this->product->getProductData($prod_id); //get main product record
$locations = $this->locations->getAvailableLocations($prod_id); //sale locations
$comments = $this->feedback->getFeedback($prod_id,'COMMENTS'); //user comments

另一方面,我们也可以这样做:$this->getAllProductData($id) 基本上会有一个SQL

get * from product_data 
left join locations on <...> 
left join comments on <...>

programming 的角度来看,第一个选项使我们更容易处理数据、混合和匹配构建单独的流程/用户体验等。我们担心的是 - 从performance 的角度来看,这是否会成为一个问题产品在数十万行中运行?

【问题讨论】:

  • 如果您按 product_id 过滤,并且在每个表上都有索引,我认为运行 3 个单独的查询比只运行一个查询更糟糕。但是您应该比较所有案例的执行计划并自己查看。将一些测试数据放在这些表上并进行测试。

标签: mysql sql performance join scalability


【解决方案1】:

每次执行 SQL 语句都会产生开销。发送到服务器的数据包、SQL 文本解析、语句验证语法正确(关键字、逗号、括号等)、语句验证语义正确(标识符引用表、列、函数等存在并且用户有足够的权限,评估可能的执行计划并选择最佳计划,执行计划(获取锁,访问缓冲区中的数据等),物化结果集(元数据和值),并返回给调用者,释放锁,清理资源等。在客户端,有检索结果集、获取行和关闭语句的开销。

一般来说,使用更少的语句检索所需的实际数据会更有效,但如果这会返回大量不需要的信息,则不会。如果我们只需要 20 行,那么我们在查询中添加LIMIT 20。如果我们只需要特定 product_id 的行,WHERE product_id = 42

当我们看到重复执行基本相同的语句的紧密循环时,这表明开发人员正在处理数据 RBER(逐行),而不是作为一个集合。

底线,这取决于用例。有时,运行几个较小的语句来代替一个庞大的语句会更有效。

【讨论】:

    【解决方案2】:

    对于简单的连接,您可能只需要一条 sql 语句即可,但根据我的经验,当涉及更多表时,多个单独的查询会更好地提高性能。

    我在一个网站上工作过,其中产品信息分散在七个不同的表中,通常只有两三个表需要连接。但是在一个页面上,我们有一个复杂的搜索功能,需要查看所有七个,所以在那个页面上,我们编写了代码以在一个语句中连接所有表。它运行良好,直到几个月后,它逐渐变得越来越慢,直到完全无法加载。

    我们检查了所有表格,并确保所有内容都已正确编入索引,并且没有任何问题可以修复它。我们注意到 sql 语句本身都运行良好,所以我们最终将其拆分为单独的语句并修复了它,不必回头再看一遍。

    【讨论】:

      【解决方案3】:

      使用您的第二个示例(一个查询中的所有联接)。只要你有一个关于“prod_id”的索引以及你过滤或加入的任何其他东西,数据库查询优化器就会做一些聪明的事情,比如看到 prod_id 只会返回几条记录,并且首先这样做会使查询尽可能快。一般来说,查询优化器非常非常擅长

      【讨论】:

        猜你喜欢
        • 2017-05-25
        • 2012-02-20
        • 2018-12-26
        • 1970-01-01
        • 2012-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-17
        相关资源
        最近更新 更多