2

テーブル レイアウトに効果的なインデックスを探しています。または、テーブルのレイアウトを変更するためのヒントが得られるかもしれません。

startendおよび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の値で名前が付けられたテーブルに新しい計算列を追加し、条件を使用できます(必ずインデックスを変更するか、新しいインデックスを作成してください)。しかし、これには問題があります。テーブルのレイアウトが悪いように感じます。誰かが更新し、計算されたものも更新するのを忘れた場合、行が壊れています。endactualWHEREWHERE remaining > 0 AND actual < 7endremainig

結果の説明:

+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 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

4

1 に答える 1