假设您的查询看起来像这样(抱歉,我放弃了尝试定位实际查询):
IF(
(SELECT aField FROM aTable WHERE bigCondition) != '0000-00-00',
SELECT aField FROM aTable WHERE bigCondition,
SELECT anotherField FROM anotherTable
)
你可以改写如下:
SELECT IF (
someField != '0000-00-00',
someField,
SELECT anotherField FROM anotherTable
)
FROM aTable WHERE bigCondition
这样你bigCondition
只计算一次。
这个查询确实很丑陋。
您的主要问题似乎是IF()
构造的滥用(和滥用,大时间)。它应该保留给简单的条件和操作。这同样适用于逻辑运算符。不要对整个查询进行操作。例如,我看到这一点在您的查询中出现了几次:
IF(
(SELECT v1.weekends FROM vendor v1 WHERE v1.vendor_id = A.vendor_id) IS NULL
OR (SELECT v1.weekends FROM vendor v1 WHERE v1.vendor_id = A.vendor_id) = '',
'6', -- by the way, why is this a string?! This is an integer, isn't it?
(SELECT v1.weekends FROM vendor v1 WHERE v1.vendor_id = A.vendor_id)
)
这是不好的。条件应直接移入SELECT
。改写如下:
SELECT
IF (v1.weekends IS NULL OR v1.weekends = '', 6, v1.weekends)
FROM vendor v1 WHERE v1.vendor_id = A.vendor_id
那是两个SELECT
得救了。对包含查询的每一个都执行此IF()
操作,我敢打赌,您将把查询速度提高几个数量级。
关于您当前的代码还有很多话要说。不幸的是,您可能需要重构 ORM 的某些部分。向某些类添加新的、更专业的方法,并使它们使用您手动制作的新查询。然后重构您当前的操作,以便它使用这些新方法。