大型不可读SQL查询的组件化使其太慢,但缺乏概念的中心定义被证明是危险的


Componentization of large unreadable SQL query makes it too slow but lack of central definitions of concepts proves dangerous

我正在努力研究如何编写代码,既要足够快,可以完成手头的任务,又要结构良好,以便将来可读和维护。

任务是用 php 生成一个销售报告,该报告利用来自 SQL 数据库的数据。此报表返回数千行,每行代表一项销售。报表的许多列必须在生成报表时计算,因为它们的值未存储在数据库中。我编写了一个大型 SQL 查询,可以非常快速地生成报告。

我的问题是这会产生代码重复,此外,人们很难从系统实体的角度理解SQL代码。例如,我的函数库中有一个函数,该函数返回收到的销售金额。它调用以下 SQL 片段来执行此操作。

SELECT SUM(amount) AS amount_received
FROM transactions
WHERE
    tran_status = 'Success' AND
    booking_id = $booking_id

创建报告时,在从数据库中获取数千笔销售后,为每笔销售调用一次此函数太慢了。因此,我将以下内容连接到我的 SELECT 语句中,以便销售额来自带有amount_received列的数据库。

SELECT booking_id, SUM(amount) AS amount_received
FROM transactions
WHERE tran_status = 'Success'
GROUP BY booking_id

在撰写本报告时,我已经使用许多不同的系统概念完成了此操作,并且我知道在多个地方定义这些关键概念是危险的,即使我也很努力阅读我的大量SQL查询。任何建议将不胜感激。

这是我的第一个问题,如果我做错了什么,很抱歉......

在 pma 中使用前导字符串"EXPLAIN "显示完整查询和执行完整查询;

它看起来像一个 N+1 查询问题。无论您做什么,报表都将是一个单独的实体,并且需要额外的框架。考虑为单个对象查询创建集合驱动的替代方案,并将它们插入到多对象集中,无论是数组还是您选择的结构。使其足够灵活,可以接收一堆 ID,然后将这些 ID 传递给您的各种组件以取回数据。然后,您可以迭代巨大的集合来计算所需的内容。注意:这种方法非常占用大量内存,因为您在接触、输出数据等之前会存储大量数据。我建议返回结果集而不是填充的数组 - 无论如何,SQL 服务器都会使用该内存。

这样,您就可以获得定义,获得更快(但仍然不是最佳(的解决方案,然后报表是关于如何运行哪些结果集以及报表到页的组成的对象。