2016-09-19 8 views
3

合計400万行のテーブルがあります。私は次のクエリを実行するとインデックス付きカラムを使用した苦しいMySQLクエリ

、それは

SELECT * FROM `traffic` 
WHERE `callstart_timestamp` >= '2016-09-01 00:00:00' 
AND `callend_timestamp` <= '2016-09-18 00:00:00' 
AND app = 'XXXX' 

416040合計を完了するために40秒かかり、クエリは、40.0631秒かかりました。

条件からAND app = 'XXXX'を削除すると、1秒未満で終了します。

すべての列のインデックスが作成されているため、この問題を引き起こしている可能性のあることについてアドバイスできますか?

クエリは、EXPLAIN:

SIMPLE; traffic; NULL; ref; app,callend_timestamp,callstart_timestamp; app; 22; const; 1976467; 12.13; Using where; 

は、CREATE:

CREATE TABLE `traffic` (
    `id` varchar(20) NOT NULL, 
    `user_cli` varchar(15) NOT NULL, 
    `ddi` varchar(15) DEFAULT NULL, 
    `callstart_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `callend_timestamp` timestamp NULL DEFAULT NULL, 
    `app` varchar(20) NOT NULL, 
    `lang` char(2) NOT NULL DEFAULT 'en' 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 


ALTER TABLE `traffic` 
    ADD PRIMARY KEY (`id`), 
    ADD KEY `app` (`app`), 
    ADD KEY `callend_timestamp` (`callend_timestamp`), 
    ADD KEY `callstart_timestamp` (`callstart_timestamp`), 
    ADD KEY `ddi` (`ddi`); 

UPDATE:

私は以下の回答の一部を実装していると、彼らは多くを助けました!私はどの答えが私の場合より優れているか把握しようとします。結果を更新します。代わりに、実行計画をオプティマイザを混同して、それぞれに別々のインデックスのすべての3列に対して1つのインデックスを追加

+1

「アプリ」のインデックスの使用を無効にするとどうなりますか?つまり、「アプリ」ではなく日付をオフにします。 –

+0

ちょっとした提案:別のテーブルに移動し、外部キーで参照してください。次に、アプリの主キーでフィルタリングします。特に、多くの行で同じアプリのvarcharを使用すると便利です。 – drodil

答えて

2

標準答えは、すべての3つの列に索引を作成することです。

インデックス列リストにものに一致するオープンエンドの範囲の前に正確に一致する列を置くの一般的な原則を次の
create index traffic_001 on traffic(app, callstart_timestamp, callend_timestamp) 

しかし、私はそれがうまくいくかもしれない前に行って見ていない別のアイデアがあります:

SELECT * FROM traffic 
WHERE callstart_timestamp between '2016-09-01 00:00:00' and callend_timestamp 
AND callend_timestamp between callstart_timestamp and '2016-09-18 00:00:00' 
AND app = 'XXXX' 

論理的に開始/終了値が互いにによって囲まれているが。おそらく、この事実をクエリにコーディングすると、インデックスを追加しなくても役に立ちます。

+1

最初のインデックスが正しいです。クエリはおそらくインデックスを使用しません。 –

+0

@gordonはおそらくそうではありませんが、アイデアはかわいいように見えました。以前は見たことがありませんでした。 – Bohemian

1

試してみてください。

CREATE INDEX idx_1 
ON traffic(app,callstart_timestamp,callend_timestamp); 
+0

これはクエリの正しいインデックスではありません。 –

+0

@GordonLinoff私の悪い。 – sagi

関連する問題