1

クエリを最適化しようとしています。

私の質問はMySQL、Union ALL、LIMITに似ているようで、答えは同じかもしれません(恐れています)。ただし、私の場合は、より厳しい制限 (1) と日時列のインデックスがあります。

だからここに行きます:

簡単にするために、3 つの列を持つ 1 つのテーブルだけにしましょう。

  • md5 (varchar)
  • 値 (varchar)。
  • 最終更新日 (日時)

(md5, updated) にインデックスがあるため、md5 キーを選択し、更新された順序で並べ替え、1 に制限すると最適化されます。

検索では、10 個の md5 キーの 1 つに一致する最大 1 つのレコードが返されます。キーには優先順位があります。したがって、prio 1 のレコードがある場合、prio 2、3 などのレコードよりも優先されます。

現在、UNION ALL が使用されています。

select * from

(

(
select 0 prio, value
from mytable
where md5 = '7b76e7c87e1e697d08300fd9058ed1db'
order by lastupdated desc 
limit 1
)

union all

(
select 1 prio, value
from mytable
where md5 = 'eb36cd1c563ffedc6adaf8b74c259723'
order by lastupdated desc 
limit 1
)

) x

order by prio
limit 1;

それは機能しますが、10 個のキーが提供された場合、UNION は 10 個のクエリすべてを実行するようです。

ただし、ビジネスの観点からは、select を順番に実行し、最初の一致後に停止しても問題ありません。

それはプレーンSQLで可能ですか?

それとも、唯一のオプションはストアド プロシージャでしょうか。

4

3 に答える 3

0

UNIONを必要としない、これを行うためのはるかに優れた方法があります。カスタムの順序で、各キーのグループごとの最大値が本当に必要です。

Groupwise Max

FIELD()による注文

于 2013-01-03T21:14:18.370 に答える
0

のオプティマイザーがUNION ALLあなたが何をしているのかを理解する方法はありません。

これができるかどうかはわかりませんが、探していることがわかっているハッシュ コードのリストを含む md5prio テーブルがあるとします。例えば。

prio   md5
0      '7b76e7c87e1e697d08300fd9058ed1db'
1      'eb36cd1c563ffedc6adaf8b74c259723'
etc

初期化。

次に、クエリは次のようになります。

    select mytable.*
      from mytable
      join md5prio on mytable.md5 = md5prio.md5
  order by md5prio.prio, mytable.lastupdated desc
     limit 1

これにより、繰り返されるクエリを節約できます。mytable.md5 に必ずインデックスが必要です。lastupdated の複合インデックスが役立つかどうかはわかりません。試してみる必要があります。

于 2013-01-03T21:15:09.917 に答える
0

あなたの場合、最も効率的な解決策は、にインデックスを作成すること(md5, lastupdated)です。このインデックスは、各サブクエリを非常に効率的に解決するために使用する必要があります (インデックス内の値を検索してから、1 つのデータ ページを検索します)。

残念ながら、Gavin が参照するグループごとの最大値は、lastupdated 値が重複している場合に複数の行を生成します (確かに、あなたの場合は問題にならないかもしれません)。

group_concat実際には、 andを使用してこの答えを取得する MySQL の方法がありますsubstring_index

select p.prio,
       substring_index(group_concat(mt.value order by mt.lastupdated desc), ',', 1)
from mytable mt join
     (select 0 as prio, '7b76e7c87e1e697d08300fd9058ed1db' as md5 union all
      select 1 as prio, 'eb36cd1c563ffedc6adaf8b74c259723' as md5 union all
      . . .
     ) p
     on mt.md5 = p.md5
于 2013-01-03T21:21:56.580 に答える