У меня есть такая таблица, в которой хранятся конфигурации различных запущенных программ.Это выглядит примерно так:
+--------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+-------+
| Date | date | YES | MUL | NULL | |
| Program | varchar(20) | YES | MUL | NULL | |
| ConfigFile | int(11) | YES | | NULL | |
| Parameter | varchar(20) | YES | | NULL | |
| Value | varchar(20) | YES | | NULL | |
+--------------+---------------+------+-----+---------+-------+
Поле ConfigFile
содержит номер файла конфигурации - для некоторых программ можно выбрать более одного файла конфигурации.
У него есть пара индексов, вот так:
+-------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| lists | 1 | Date | 1 | Date | A | 1108060 | NULL | NULL | YES | BTREE | | |
| lists | 1 | Date | 2 | Program | A | 1108060 | NULL | NULL | YES | BTREE | | |
| lists | 1 | Date | 3 | Parameter | A | 1108060 | NULL | NULL | YES | BTREE | | |
| lists | 1 | Program | 1 | Program | A | 4676 | NULL | NULL | YES | BTREE | | |
| lists | 1 | Program | 2 | Parameter | A | 183706 | NULL | NULL | YES | BTREE | | |
+-------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Теперь давайте скажем, что я хочу знать, каковы параметры для данной программы.Похоже, я должен быть в состоянии сделать что-то вроде этого:
SELECT DISTINCT Parameter FROM params WHERE Program = 'MyProgram';
Это имеет следующий план объяснения:
+----+-------------+--------+------------+------+----------------+---------+---------+-------+-----------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+----------------+---------+---------+-------+-----------+----------+--------------------------+
| 1 | SIMPLE | params | NULL | ref | Date,Program | Program | 23 | const | 137203382 | 100.00 | Using where; Using index |
+----+-------------+--------+------------+------+----------------+---------+---------+-------+-----------+----------+--------------------------+
Есть что-то вроде 15 различных вариантов для Program
,и, возможно, от 10 до 100 значений Parameter
для каждой программы.
С моим пониманием того, как работает индекс базы данных, я ожидаю, что это завершится мгновенно.В частности, я ожидаю, что базовой структурой данных будет дерево бинарного поиска с 15 узлами, которое я ищу, чтобы найти то, которое соответствует моей программе;после нахождения моей программы, я перехожу ко второму бинарному поисковому дереву с, возможно, 100 или менее узлами, которое я тогда просто обойду.
Когда я на самом деле запускаю запрос, хотя онв итоге занимает несколько минут.
Для меня это говорит о том, что возможно существует несколько копий одного и того же значения в дереве двоичного поиска, по одной на узел таблицы.Это то, что происходит, и, если да, что я могу сделать, чтобы смягчить эту ситуацию?
Я подумал о том, чтобы иметь одну таблицу с уникальными тройками (Дата, Программа, Параметр) и иметь отношение, но я неуверен, как выполнить массовую вставку данных в этой ситуации.И если я ошибаюсь из-за того, почему это так медленно, то, конечно, это даже не поможет.