含まれているテーブルからの行だけ過去週間以内に
SELECT ...
FROM very_big_unindexed_table t
...
WHERE t.timestamp >= NOW() + INTERVAL - 1 WEEK
は '?キロワット=' エントリポイントで
AND t.entrypoint LIKE '%?kw=%'
のみ各IPの最新の行それにはいくつかのアプローチがあります。非常に大きな索引付けされていない表の相関サブクエリは、あなたのランチとランチボックスを食べます。また、索引がなければ、表と「ファイル・ポートの使用」操作を完全にスキャンすることはありません。
パフォーマンスが悪い場合は、できるだけ小さくしてから並べ替えを実行し、結合操作(そのテーブルに戻る)を避けて相関関係を避けるサブクエリ。
だから、先週の行のすべてのを「?kw =」というエントリポイントで返してみましょう。これは
SELECT t.ip
, t.timestamp
, t.entry_point
FROM very_big_unindexed_table t
WHERE t.timestamp >= NOW() + INTERVAL -1 WEEK
AND t.entrypoint LIKE '%?kw=%'
ORDER BY t.ip DESC, t.timestamp DESC
我々は、ユーザー定義変数と、サポートされていないトリックを使用することができます...完全なテーブルのスキャン、およびソート操作になるだろう。動作は(正式に)未定義。非公式には、MySQL 5.1および5.5(少なくとも)非常に予測可能である。
私はこれがあると思うでオプティマイザであるため、(MySQLのリファレンスマニュアルには具体的には、このようなパターンを使用しないように警告し先週の行の数がテーブル全体の重要なサブセットである場合、あなたが得ようとしているものと同程度になるでしょう。これは、行がたくさんある場合には、かなりの中間結果セット(派生テーブル)それらは述語を満たす。
SELECT q.ip
, q.entrypoint
, q.timestamp
FROM (
SELECT IF(t.ip = @prev_ip, 0, 1) AS new_ip
, @prev_ip := t.ip AS ip
, t.timestamp AS timestamp
, t.entrypoint AS entrypoint
FROM (SELECT @prev_ip := NULL) i
CROSS
JOIN very_big_unindexed_table t
WHERE t.timestamp >= NOW() + INTERVAL -1 WEEK
AND t.entrypoint LIKE '%?kw=%'
ORDER BY t.ip DESC, t.timestamp DESC
) q
WHERE q.new_ip
そのクエリの実行(時間を取るために何が起こっているかの点で)が必要になります
- テーブルのフルスキャン(その周りを取得する方法はありません)
- ソート
- 述語を満足するすべての行を含む導出表をマテリアライズして、導出表を通過させてeの「最新」行を引き出す(述語を満足する行をすべて含む)。
- ach IP
クエリが何であれ、速度は遅くなり、速度の差は最小限に抑えられます。 Mysqlはすべて索引に関するものです。 – cpugourou
インデックスがない場合、エンジンはフルテーブルスキャンを実行する必要があります。制限句がある場合、早期に停止する可能性がありますが、実行できるショートカットはありません。 (わからない場合は、クエリでEXPLAINを実行してください。) –
「非常に大きい」の大きさは? –