1

~5m の行テーブルに後続があるすべての毎時レコードを見つけたいと思っていました。

私は試した :

SELECT DISTINCT (date_time)
FROM my_table
JOIN (SELECT DISTINCT (DATE_ADD( date_time, INTERVAL 1 HOUR)) date_offset
      FROM my_table) offset_dates
ON date_time = date_offset

SELECT DISTINCT(date_time)
FROM my_table
WHERE date_time IN (SELECT DISTINCT(DATE_ADD(date_time, INTERVAL 1 HOUR))
                    FROM my_table)

最初のものは数秒で完了し、秒は数時間ハングします。早ければ早いほどよいことは理解できますが、なぜこれほど大きなパフォーマンスの差が生じるのでしょうか?

- - - - 編集 - - - - - - - -

ここEXPLAINに両方の​​クエリがあります

id  select_type table       type    possible_keys   key     key_len ref                         rows    Extra
1   PRIMARY     <derived2>  ALL     NULL            NULL    NULL    NULL                        1710    Using temporary
1   PRIMARY     my_table    ref     PRIMARY         PRIMARY 8       offset_dates.date_offset    555     Using index
2   DERIVED     my_table    index   NULL            PRIMARY 13      NULL                        5644204 Using index; Using temporary


id  select_type        table    type    possible_keys   key     key_len ref     rows    Extra
1   PRIMARY            my_table range   NULL            PRIMARY 8       NULL    9244    Using where; Using index for group-by
2   DEPENDENT SUBQUERY my_table index   NULL            PRIMARY 13      NULL    5129983 Using where; Using index; Using temporary
4

4 に答える 4

1

'IN' 句は、通常、巨大なテーブルに対して低速です。私が覚えている限りでは、印刷した 2 番目のステートメントについては、my_table のすべての行を単純にループして (そこにインデックスがない限り)、各行で WHERE 句の一致をチェックします。一般に、IN はすべてのセット要素を含む OR 句のセットとして扱われます。そのため、JOIN クエリのバックグラウンドで作成される一時テーブルを使用する方が高速だと思います。

これに関するいくつかの役立つリンクを次に示します。

MySQL Query IN() 句がインデックス付きカラムで遅い

内部結合とどこで()句のパフォーマンス?

http://explainextended.com/2009/08/18/passing-parameters-in-mysql-in-list-vs-temporary-table/

于 2013-08-06T16:20:51.537 に答える
1

考慮すべきもう 1 つの点は、IN スタイルでは、JOIN と比較して将来の最適化がほとんどできないということです。結合を使用すると、インデックスを追加できる可能性があります。これは、データセットによって異なりますが、2、5、10 倍高速化される可能性があります。IN を使用して、そのクエリを実行します。

于 2013-08-06T16:57:09.777 に答える