0

クエリがスムーズに実行されるように、インデックスを作成する方法を教えてください。

現在、8k+ またはレコードを返す以下のクエリがあります。ただし、完了するまでに 2 秒以上かかります。tblproduction の現在の記録は 1600 万以上です

SELECT COUNT(fldglobalid) AS PackagesDone
  FROM tblproduction
 WHERE fldemployeeno = 'APD100401'
   AND fldstarttime BETWEEN '2013-08-14 07:18:06' AND '2013-08-14 16:01:58'
   AND fldshift = 'B'
   AND fldprojectgroup = 'FTO'
   AND fldGlobalID <> 0;

現在のインデックスを下回っていますが、それでもクエリの実行時間が長くなります

Index_1
  fldEmployeeNo
  fldStartTime

Index_2
  fldEmployeeNo
  fldTask
  fldTaskStatus

Index_3
  fldGlobalId
  fldProjectGroup

Index_4
  fldGlobalId

FORCE_Index を使用してこのインデックスをすべて使用しましたが、それでもクエリの実行時間が長くなります。

アドバイスしてください、ありがとう!

4

2 に答える 2

2

これはゴードン・リノフの回答のコメントとして始まりましたが、長すぎます。

It would be better to include fldGlobalId in the index as well- いいえ、そうではありません - これはパフォーマンスにとって逆効果です - データの取得速度は向上しませんが (クエリは不等式には使用されません)、インデックスの更新頻度が高くなるため、インデックスの断片化が増加します (したがって、パフォーマンスが悪化する可能性があります)。 SELECT のパフォーマンス) および挿入と更新のパフォーマンスの低下。

理想的には、すべてのクエリを最適化するようにスキーマを設計する必要があります。これはかなり大きなタスクですが、提供したのは 1 つだけなので....

現状のクエリは、解決のために単一のインデックスのみを使用するため、インデックスには、一致しないもの (つまり、fldGlobalID)を除いて、クエリ内の述語を持つすべてのフィールドを含める必要があります。

フィールドの順序は重要です。述語のセットが異なる他のクエリがない場合は、相対的なカーディナリティが最も高いフィールドを最初に配置する必要があります。データ (SELECT COUNT(DISTINCT field)/COUNT(*) FROM yourtable) を分析せずにこれが何であるかを知るのはかなり難しいですが、推測では、順序は fldstarttime、fldemployeeno、fldprojectgroup、fldshift である必要があります。

fldemployeeno から fldshift への依存がある場合 (つまり、従業員は常に、または少なくとも約 90% 以上の時間)、インデックスに fldshift を含めることは、インデックスのサイズを増やすだけであり、効率を向上させることにはなりません。

使用しているインデックスのタイプはわかりませんでした-btreeは範囲で機能し、ハッシュは不等式で機能します。ここでのカーディナリティが最も高い述語は範囲を使用しているため、btree インデックスはハッシュ ベースのインデックスよりもはるかに効率的です。

于 2013-08-14T12:27:02.007 に答える