我正在处理一个包含大量SQL查询的应用程序。它们非常复杂,当我完成理解时,我已经忘记了它是如何开始的。
我想知道从数据库中提取更多数据并使用Python在我的代码中进行最终查询是否是一个好习惯。我疯了吗?性能会不好?
请注意,结果也很大,我说的是其他人开发的ERP生产中的。
答案 0 :(得分:7)
让DB弄清楚如何最好地检索您想要的信息,否则您将不得不在代码中复制RDBMS的功能,这将比您的SQL查询更复杂。
另外,您将浪费时间将所有不需要的信息从数据库传输到您的应用程序,以便您可以在代码中过滤和处理它。
所有这一切都是真的,因为你说你正在处理大数据。
答案 1 :(得分:3)
我会尽可能地在应用程序中使用业务逻辑。查询中的复杂业务逻辑很难维护。 (当我完成理解一个我已经忘记它是如何开始的)存储过程中的复杂逻辑是可以的。但是对于一个典型的python应用程序,你会希望你的业务逻辑是python。
现在,数据库在处理数据方面比应用程序代码更好。因此,如果您的逻辑涉及大量数据,您可以使用数据库中的逻辑获得更好的性能。但这将适用于大量数据的复杂报告,簿记操作等。您可能希望使用存储过程或专门用于此类操作的系统(报表的数据仓库)。
正常 OLTP操作不涉及太多数据。数据库可能很庞大,但典型交易所需的数据(通常)只是其中的一小部分。在一个大的数据库查询,这可能会导致性能问题,但你可以通过多种方式优化这个(索引,全文搜索,冗余,汇总表...取决于你的实际问题)。
每个规则都有例外,但作为一般的指南,请尝试在您的应用程序代码中使用您的业务逻辑。复杂逻辑的存储过程。一个单独的数据仓库或一组报告程序。
答案 2 :(得分:1)
我的经验是你应该让数据库进行处理。它比首先从db中检索所有数据要快得多,并且有一些代码可以加入并过滤结果。
这里的难点在于记录您的查询,因此如果您在一段时间后查看它们,其他人(甚至您)将会了解正在发生的事情。我发现大多数数据库都允许SQL中的注释。有时在/ * comment * / tags之间,有时用 - comment注释一行。
文档化的查询可能如下所示
select name, dateofbirth from (
-- The next subquery will retrieve ....
select ....
) SR /* SR SubResults */
....
答案 3 :(得分:1)
@Nivas通常是正确的。
这些是非常常见的模式
分工 - DBA必须返回业务所需的所有数据,但它们只有一个可以使用的数据库。开发人员可以与DBA合作以更好地完成任务,但部门负责人几乎不可能做到这一点。因此,使用SQL来执行更多检索数据。
缺少较小的功能。使用工作表可以将大量查询分解为更小的阶段吗?是的,但我知道一个新表需要大量审批的环境 - 一个繁重的查询只是写的
因此,通常情况下,从数据库中获取数据 - 即数据库。但是如果SQL查询太长,RDBMS就难以优化,这可能意味着查询一次性跨越数据,业务逻辑甚至呈现。
我建议一种更为理智的方法通常是将“获取数据”部分分离到存储过程或填充登台表的其他可控查询中。然后可以将业务逻辑写入上面的脚本语言并控制存储过程。演示文稿留在别处。从本质上讲,像cognos这样的解决方案试图做到这一点。
但如果您正在研究生产中的ERP,那么上述约束和解决方案可能已经存在 - 您是否正在与合适的人交谈?
答案 4 :(得分:0)
我的一个应用程序(B)使用tempdb将复杂查询拆分为批处理。另一个应用程序(B)在没有它的情况下使用复杂查询。
App A对大型数据库更有效。
但是要看一下你的情况,你可以像这样执行DMV脚本:
-- Get top total worker time queries for entire instance (Query 38) (Top Worker Time Queries)
SELECT TOP(50) DB_NAME(t.[dbid]) AS [Database Name], t.[text] AS [Query Text],
qs.total_worker_time AS [Total Worker Time], qs.min_worker_time AS [Min Worker Time],
qs.total_worker_time/qs.execution_count AS [Avg Worker Time],
qs.max_worker_time AS [Max Worker Time], qs.execution_count AS [Execution Count],
qs.total_elapsed_time/qs.execution_count AS [Avg Elapsed Time],
qs.total_logical_reads/qs.execution_count AS [Avg Logical Reads],
qs.total_physical_reads/qs.execution_count AS [Avg Physical Reads],
qp.query_plan AS [Query Plan], qs.creation_time AS [Creation Time]
FROM sys.dm_exec_query_stats AS qs WITH (NOLOCK)
CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS t
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS qp
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);
然后您可以打开重量级查询的查询计划并尝试搜索类似的内容:
StatementOptmEarlyAbortReason ="超时" 要么 StatementOptmEarlyAbortReason =" MemoryLimitExceeded"
这些事实告诉您将复杂查询拆分为batch + tempdb
PS。它适用于没有索引/表扫描,缺少索引等的良好查询。