2017-11-27 6 views
2

私は約600.000エントリのテーブルを持っています。テーブルは:MySQLが主キーオーバーインデックスを選択しています

私は(start、end、room_id)でインデックスを作成しました。これはSELECTクエリに大きなパフォーマンスをもたらしました。しかし、今、私は次のクエリを実行している:

update vacancies 
    set locked = 1 
    where start >= '2017-11-28 22:00:00' 
     and end <= '2017-11-28 23:00:00' 
     and (room_id = 1234 
      or room_id in (select other_room 
        from room_dependencies 
        where first_room = 1234)) 

私はこのクエリは、それが(〜1.5秒)をやっていることのために時間のかなり多くを取ると信じています。私は、MySQL上でEXPLAINコマンドを実行し、それが次のように返さ:

EXPLAIN results

(私は(はるかに)DBの専門家ではないが、私はこのクエリは、全表スキャンを実行していたことを奇妙だと思ったFTS )を使用する代わりに、INDEX(start、end、room_id)を使用します。どうやら、それは実行可能なキーとして "開始"を識別し、それを無視して、PRIMARY KEYを選択し、FTSを実行します。そこで、私はthis answerに続き、PRIMARY KEYを削除し、新しいPRIMARY KEYとして(start、end、room_id)を追加しましたが、結果はまったく同じ(または最悪の場合もありました)。

これは、プラットフォーム上の他のアクションの直後に実行する必要がある単一の要求です。キューに入れて遅延形式で更新された他のバッチとして実行することは不可能です。

このクエリのパフォーマンスを向上させる方法は他にありますか?

ありがとうございます!

+0

他の選択肢はどのように見えますか?通常、複数列の索引の最後に範囲が必要な列を指定します(room_id、start、end)。私はそれを望んでいるか、room_idのインデックスだけを追加したいと思う。あるいは、単に '空き状況の更新がインデックス(開始)セットを使用する... 'と言うだけで十分です。 – ysth

+0

(tinyintの意味がない場合は '1') – Strawberry

+1

開始時刻> = '2017-11-28 22:00:00'の行の数はいくつですか?'どこでスタート> = '2017-11-28 22:00:00'を試して、<2017-11-28 23:00:00 'を開始し、<=' 2017-11-28 23:00:00に終了しましたか? 'AND ...'?オプティマイザは、目的の終了時刻の後に開始する行を排除できることを直観的に理解していません。 –

答えて

0

MySQL in条件はインデックスを利用しません。代わりにinner joinを試してください。

update vacancies 
    inner join 
    (select other_room 
      from room_dependencies 
      where first_room = 1234) t2 
    on vacancies.room_id = t2.other_room 
    set locked = 1 
    where start >= '' 
      and end <= ''; 

とroom_id =のみ1234と他の更新を行います。

0

範囲が2つの別個の属性で表されるため、開始値と終了値にはおそらく少数の行が指定されますが、DBMSは最初にstart >= '2017-11-28 22:00:00'のすべての単一インデックスエントリを読み取る必要があります。 end <= '2017-11-28 23:00:00'を満足する。 DBMSは、これが高価な操作であることを認識しています。

この問題を解決するには2つの方法があります。 1つは、事前定義されたブロックセット内で範囲を分割し、それらのブロックのそれぞれを空きテーブルにリンクすることです(これは面倒で、まだ効率的ではありません)。

正しい解決策は、時間を1次元空間として扱い、geo-spatial indexingを適用することです。 MySQLでは、地理空間座標は2次元しか持てないため、時間範囲を2D空間にマップする必要があります。インターネットにはこれを行う方法の例がたくさんありますがwith IP addressesですが、MySQLと日付範囲に関する具体的な内容は見ていません。例はusing SQL Serverです。

時間をかけて部屋を借りることに注目することに興味があります!

関連する問題