テーブル レイアウトに効果的なインデックスを探しています。または、テーブルのレイアウトを変更するためのヒントが得られるかもしれません。
start
、end
およびactual
値(タイムスタンプ、以下の例では低い数字で簡略化されています)を含むテーブルがあります。actual
に達するまで増やすことができますend
。
CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`start` int(10) unsigned NOT NULL DEFAULT '0',
`actual` int(10) unsigned NOT NULL DEFAULT '0',
`end` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `actual` (`actual`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `t1`
(`id`, `start`, `actual`, `end`)
VALUES
(1, 1, 0, 5),
(2, 1, 6, 6),
(3, 2, 8, 9),
(4, 2, 5, 9);
私のSELECT
結果では、現在のタイムスタンプよりも小さい値を持つテーブルのすべての行が必要ですactual
(例を簡単にするために、現在のタイムスタンプが7であるとしましょう)。actual
さらに、値が よりも小さいこれらの行のみが必要ですend
。この 2 番目の条件が問題になります。
SELECT `id`
FROM `t1`
WHERE `actual` < `end`
AND `actual` < 7;
+----+
| id |
+----+
| 1 |
| 4 |
+----+
2 rows in set (0.00 sec)
インデックスは に使用されますがactual < 7
、 には使用されないと思いますactual < end
。の比較はactual < end
すべての古い行に対して行われるため、クエリはテーブル内の新しい (古い) 行ごとに遅くなります。
end < 7
結果に古い行が必要なため、問題は解決しませんactual < end
。
-remaining
の値で名前が付けられたテーブルに新しい計算列を追加し、条件を使用できます(必ずインデックスを変更するか、新しいインデックスを作成してください)。しかし、これには問題があります。テーブルのレイアウトが悪いように感じます。誰かが更新し、計算されたものも更新するのを忘れた場合、行が壊れています。end
actual
WHERE
WHERE remaining > 0 AND actual < 7
end
remainig
結果の説明:
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | t1 | ALL | actual | NULL | NULL | NULL | 4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
キー定義を次のように変更します。
KEY `actual_end` (`actual`,`end`)
結果の説明:
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+
| 1 | SIMPLE | t1 | range | actual_end | actual_end | 4 | NULL | 3 | Using where; Using index |
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+
この最後の Explain は、インデックスがではなくのためにactual < 7
使用されることを証明します。10 億の古い行がある場合、最後の条件は 10 億の行を調べます。この問題を最適化したい。actual < end