クエリが次のようになっていると仮定します (申し訳ありませんが、実際のクエリを見つけるのをあきらめました)。
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()
です。単純な条件と操作に限定する必要があります。同じことが論理演算子にも当てはまります。クエリ全体を操作しないでください。たとえば、次の 1 つのビットがクエリに数回表示されます。
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
これで2人SELECT
救われました。クエリを含むすべてIF()
のクエリに対してこれを実行すると、クエリが数桁高速化されることは間違いありません。
現在のコードについては、さらに多くのことが言えます。残念ながら、おそらく ORM の一部をリファクタリングする必要があります。一部のクラスに、より特化した新しいメソッドを追加し、手動で作成した新しいクエリを使用するようにします。次に、現在の操作をリファクタリングして、これらの新しいメソッドを使用するようにします。