私はこれを数日前にSQL最適化の後に考えていました。SQLはウィキペディアの定義における「宣言型言語」であることに同意できると思います。
制御フローを記述せずに計算のロジックを表現するプログラミングパラダイム
カーテンの後ろで何が行われるかを考える場合(統計を見て、インデックスが有用かどうかを判断し、ネスト、マージ、またはハッシュ結合などに進む)など、高レベルを与えることを認める必要があります。ロジック、およびデータベースがすべての低レベル制御フローロジックを処理しました。
また、このシナリオでは、最良の結果を得るために、データベースオプティマイザーがユーザーからの「ヒント」を必要とする場合があります。
「宣言的」言語のもう1つの一般的な定義は次のとおりです(正式なソースが見つかりません)。
計算の目的の結果を、それを達成するための手順を説明せずに表現するプログラミングパラダイム
この定義を受け入れると、OPで説明されている問題が発生します。
最初の問題は、SQLが「同じ結果」を定義するための複数の同等の方法を提供することです。おそらくそれは必要な悪です。言語に表現力を与えるほど、同じものを表現するさまざまな方法がある可能性が高くなります。
例として、このクエリを最適化するように一度求められました。
SELECT Distinct CT.cust_type, ct.cust_type_description
from customer c
INNER JOIN
Customer_type CT on c.cust_type=ct.cust_type;
タイプは顧客よりもはるかに少なく、cust_type
on customerテーブルにインデックスがあったため、次のように書き直すことで大きな改善を達成しました。
SELECT CT.cust_type, ct.cust_type_description
from Customer_type CT
Where exists ( select 1 from customer c
Where c.cust_type=ct.cust_type);
この特定のケースでは、開発者に何を達成したいかを尋ねると、「少なくとも1人の顧客がいるすべての顧客タイプが欲しい」と言われましたが、それは偶然にもオプティマイザークエリの記述方法です。
それで、同等でより効率的なクエリを見つけることができた場合、オプティマイザーで同じことができないのはなぜですか?
私の最良の推測は、主に次の2つの理由によるものです。
SQLはロジックを表現します:
SQLは高レベルのロジックを表現するため、オプティマイザーが私たちと私たちのロジックを「裏切る」ことを本当に望んでいますか?オプティマイザーが最も効率的な実行パスを選択するように強制する必要が常になかった場合、私は熱心に「はい」と叫ぶでしょう。オプティマイザが最善を尽くす(ロジックの修正も可能)が、何かがおかしくなったときに救助に来る「ヒントメカニズム」を提供することだと思います(ホイール+ブレーキを入れるようなものです)自動運転車)。
より多くの選択肢=より多くの時間
最高のRDBMSオプティマイザーでさえ、可能な限りすべての実行パスをテストするわけではありません。それらは本当に高速でなければならないためです。そして、それはオプティマイザーが「高レベルのロジック」を尊重していることです。同等のSQLクエリもすべてテストする必要がある場合、オプティマイザーの時間は複数回長くなる可能性があります。
no RDBMSが実際に実行できるクエリ書き換えの別の良い例は(この興味深いブログ投稿から)です
SELECT t1.id, t1.value, SUM(t2.value)
FROM mytable t1
JOIN mytable t2
ON t2.id <= t1.id
GROUP BY t1.id, t1.value;
このように書くことができる(分析関数が必要)
SELECT id, value, SUM(t1.value) OVER (ORDER BY id)
FROM mytable
select whatever from sometable where FKValue in (select FKValue from sometable_2 where other_value = :param)
。とのことを修正再表示する方法を確認するのは簡単であるべきexists
かjoin
。