私のバックグラウンドはアプリケーションプログラミングであり、最適化に関しては、JITなどのコンパイラを「考え抜こう」としないようにというガイドラインがあります。
これはSQLクエリにも当てはまりますか?
つまり、SQLサーバーは、最適であると予想されるクエリに対してある種の実行プランを実行しますが(右?)、実際のクエリを再配置/変更しますか?
または、プログラマーはクエリが最適であることを確認する必要がありますか?たとえば、最初に選択してからjoin
など
4 に答える
データベース サーバー ベンダーでの作業を含む、私の経験は次のとおりです。
まず、データベースは高度に最適化されており、マシン コード (多くの場合 C または C++ で記述) にコンパイルされています。最新の機器では、ほとんどの操作が非常に高速であるため、次善の実行は気付かれません。
ただし、注意すべき領域がいくつかあります。
インデックスがない場合、データベースはテーブル スキャンを実行する必要があり、処理が遅くなる可能性があります。多くの人は 1 つのフィールドだけをインデックスに入れますが、複数のフィールドが適用されることを考慮する必要があります。説明ユーティリティは、見つかったインデックスを表示し、どのインデックスが役立つかを提案するためにあります。
相互に関連するクエリは遅くなる可能性があります。また、式を含む where 句がある場合、データベースはレコードごとにそれを評価する必要があり、インデックスを使用できません。
接続を開くのは時間がかかるため、操作ごとに接続を再利用し、再度開かないようにしてください。
ただし、今日の最大の問題は、通常、データベース クライアントとデータベース サーバー間のネットワーク通信です。データベースへのネットワーク ターンを最小限に抑え、データベース フィルタの結果を取得して、ネットワーク経由で送信する必要があるデータを少なくするようにしてください。
データベースに任せたいこともあれば、人にしかできないこともあります。データベースの管理は、データベースそのものに任せることはできません。人々が関与しなければなりません。
データベースの最適化は芸術であると同時に科学でもあります。データベースは、既に作成されているインデックスから最適なインデックスを選択することで、クエリを最適化する優れた機能を果たします。ただし、データベースは最適なインデックスを自動的に作成しません。最適なインデックスを決定するのは、DBA/プログラマの仕事です。
インデックスを使用するとクエリが非常に高速になる場合がありますが、1 GB のメモリが必要になる場合があります。これは、一般的に追加したいインデックスではありません。ただし、クエリを見て、クエリをわずかに再フォーマットするだけで十分であることがわかります。
データ自体の知識を持つ開発者は、使用するインデックスなどについて適切な決定を下すことができます。インデックスを調べて、それらのいくつかが使用されているかどうかを確認することもお勧めします。別のインデックスが常に優れているか、インデックスを必要とする検索が実行されないため、インデックスが作成されてもデータベースで使用されないことがあります。
そのため、データベースは、既存のインデックスに基づいてクエリを最も効率的に実行する方法を決定しますが、データベースが適切なインデックスを持っているかどうかを分析し、適切なアクションを実行するのは私たちの仕事です。
一般的に、アドバイスは良いです。最適化エンジンの作成には、管理するよりもはるかに多くの人年の開発が費やされます。
とはいえ、すべてのデータベースには間違いなく落とし穴があります。場合によっては、より効率的にするために、特定のロジックを特定の方法で表現する必要があります。または、正しい実行パスを取得するためにヒントを追加する必要がある場合があります。
これは、SQLの最適化は、他の言語の最適化よりも一般的にはるかに難しいためです。最良の解決策に到達するには、データと値の分布を理解する必要があります。
私のアドバイスは、あなたがやりたいことを最もよく表す方法でクエリを書き、クエリの目的を伝える命名規則とインデントでそれらを書くことです。そうすれば、クエリを変更する必要がある場合でも、少なくともクエリが何をしているのかを理解できます。
あなた自身の知識が役に立つ状況があります。下記は用例です。
1-今月のすべてが必要です。これは簡単です
where Year(datefield) = 2013
and month(datefield) = 'February'
しかし、これはより速く実行されます
where datefield >= '2013-02-01'
and datefield < '2013-03-01'
2-あなたはパットという名前の男の子が欲しいです。性別は索引付けされていますが、名前は索引付けされていません。これは速いです
where sex = 'M'
and name = 'Pat'
これより
where name = 'Pat'
and sex = 'M'
3-ケース構成で、最初に最も頻繁に発生する状況をリストします。これ
case when something that almost always happens then 'yes' else 'no' end
より速く実行されます
case when something that almost never happens then 'no' else 'yes' end