テーブル構造:
CREATE TABLE `mytable` (
`id` varchar(8) NOT NULL,
`event` varchar(32) NOT NULL,
`event_date` date NOT NULL,
`event_time` time NOT NULL,
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
このテーブルのデータは次のようになります。
id | event | event_date | event_time
---------+------------+-------------+-------------
ref1 | someevent1 | 2010-01-01 | 01:23:45
ref1 | someevent2 | 2010-01-01 | 02:34:54
ref1 | someevent3 | 2010-01-18 | 01:23:45
ref2 | someevent4 | 2012-10-05 | 22:23:21
ref2 | someevent5 | 2012-11-21 | 11:22:33
テーブルには、これに類似した約500.000.000レコードが含まれています。
ここで質問したいクエリは次のようになります。
SELECT *
FROM `mytable`
WHERE `id` = 'ref1'
ORDER BY event_date DESC,
event_time DESC
LIMIT 0, 500
EXPLAIN
出力は次のようになります。
select_type: SIMPLE
table: E
type: ref
possible_keys: id
key: id
key_len: 27
ref: const
rows: 17024 (a common example)
Extra: Using where; Using filesort
目的:このクエリはWebサイトによって生成され、LIMIT
-valuesはページナビゲーション要素用であるため、ユーザーが古いエントリを表示したい場合は、に調整さ500, 500
れ1000, 500
ます。
フィールド内の一部の項目はid
非常に多くの行に設定できるため、行が増えると、もちろんクエリが遅くなります。これらの遅いクエリをプロファイリングすると、その理由は並べ替えであることがわかりました。ほとんどの場合、クエリ中はmysqlサーバーがデータの並べ替えでビジー状態になっています。フィールドにインデックスを付けても、それほど変更はありませんでしたevent_date
。event_time
結果の例SHOW PROFILE
、期間でソート:
state | duration/sec | percentage
---------------|--------------|-----------
Sorting result | 12.00145 | 99.80640
Sending data | 0.01978 | 0.16449
statistics | 0.00289 | 0.02403
freeing items | 0.00028 | 0.00233
...
Total | 12.02473 | 100.00000
今の質問:
他のサーバー構成オプションなどのmysql変数を深く掘り下げる前にsort_buffer_size
、クエリまたは並べ替えの動作を変更する方法を考えてみてください。そうすれば、並べ替えはパフォーマンスを大幅に低下させることはなく、このクエリの目的は引き続き有効です。
私は少し独創的な考えを気にしません。
前もって感謝します!