假設你的查詢看起來像這樣(對不起,我放棄了試圖找到實際的查詢):
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的某些部分。爲某些類添加新的更專業的方法,並使其使用您手動製作的新查詢。然後重構您的當前操作,以便它使用這些新方法。
+1因爲你沒有包含的代碼中的問題,那面牆。 –
我的建議是重寫從相關子查詢「內部查詢」(他們現在)到'LEFT'加入你的主查詢的'FROM'子句。它可能會提高效率的原因有兩個:1.他們不需要計算兩次,也不必爲每行'訂單'運行一次。 –
我很欣賞你的建議,但是我的查詢是根據參數從不同類的許多函數生成的。我希望你已經看到了完整的查詢。我害怕在這個大規模的任何重組他們 –