9

えーと、私は年を取りすぎているのかもしれませんが、次のことを理解したいと思います。

クエリ1。

select count(*), gender from customer
group by gender

クエリ2。

select count(*), 'M' from customer
where gender ='M'
union
select count(*), 'F' from customer
where gender ='F'

最初のクエリは単純ですが、プロファイラーで何らかの理由で両方を同時に実行すると、クエリ2が39%の時間を使用し、クエリ1が61%を使用していると表示されます。

その理由を理解したいのですが、すべてのクエリを書き直さなければならないかもしれません。

4

4 に答える 4

5

クエリ2は実際には素晴らしいトリックです。これは次のように機能します。性別に関するインデックスがあります。DBMSは、そのインデックスを2回シークして、2つの範囲の行(1つはM用、もう1つはF用)を取得できます。これらの行から何も読み取る必要はありません。存在するだけです。2つの範囲に存在する行数をカウントできます。

最初のクエリでは、DBMSは行をデコードして性別を読み取る必要があります。次に、行を並べ替えるか、ハッシュテーブルを作成してそれらを集約する必要があります。これは、単に行を数えるよりもコストがかかります。

于 2012-06-07T13:04:00.310 に答える
2

本気ですか?たぶん、2番目のクエリは最初からキャッシュされたリソースを使用しているだけです。

それらを2つの別々のバッチで実行し、それぞれを実行する前DBCC FREEPROCCACHEにキャッシュをクリーンアップします。次に、各実行プランの値を比較します。

于 2012-06-07T13:16:50.500 に答える
0

クエリの最適化はデータベースによって異なります。表示されているのはデータベース固有です。

記述されているように、ユニオンは、フィルターとカウントを実行して、データを2回通過する必要があります。基本的に、他のストレージは必要ありません。

集計により、データが並べ替えられてからカウントされる場合があります。または、ハッシュテーブルを生成する場合があります。パフォーマンスの違いを考えると、ソートが使用されていると思います。明らかに、これはこのタイプのクエリにとってはやり過ぎです。

性別のインデックスがある場合、どちらの方法でも基本的にインデックスがスキャンされるため、パフォーマンスは同じになるはずです(ユニオンバージョンでは2回スキャンされる可能性があります=。

使用しているデータベースは、テーブルの統計を計算する方法を提供していますか?その場合は、統計を更新して、同じ結果が得られるかどうかを確認する必要があります。

また、「説明」の結果や実行計画を投稿していただけますか?それは、一方が他方よりも速い理由を正確に説明します。

于 2012-06-07T13:12:39.863 に答える
0

同等のクエリを試しましたが、逆の結果が見つかりました。ユニオンは65%を占め、「group by」は35%を占めました。(SQL Server 2008を使用)。性別のインデックスがないため、実行プランにクラスター化インデックススキャンが表示されます。実行計画を詳細に検討しない限り、この結果を説明することは実際には不可能です。

このクエリにインデックスを追加することは、おそらく良い考えではありません。顧客テーブルにレコードを挿入するほど頻繁にこのクエリを実行することはないからです。ビットマップインデックスを備えた他のデータベースエンジン(Oracle、PostgreSQL)では、データベースエンジンが複数のインデックスを組み合わせることができるため、単一列インデックスのユーティリティを変更できます。ただし、SQL Serverでは、一般的に使用されるクエリを「カバー」するようにインデックスを設計する必要があります。

于 2012-06-07T13:34:42.897 に答える