Показать сообщение отдельно
Старый 05.12.2006, 23:28     # 1
mmaaxx
Junior Member
 
Регистрация: 08.10.2003
Сообщения: 98

mmaaxx Известность не заставит себя ждать
Unhappy MySQL: Уменьшение размера ключа привело к увеличению размера индекса. Почему?

MYSQL version(): 5.1.11-beta-debug-log

Была такая таблица (переименована в *_original) :
PHP код:
'events_original''CREATE TABLE `events_original` (
  `equipment_id` varchar(16) NOT NULL DEFAULT '
0',
  `sensor` tinyint(3) unsigned NOT NULL DEFAULT '
0',
  `type` tinyint(3) unsigned NOT NULL DEFAULT '
0',
  `time` int(10) unsigned NOT NULL DEFAULT '
0',
  `data` double DEFAULT NULL,
  `message` text,
  KEY `equipmentid` (`equipment_id`,`sensor`,`time`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1' 
Размеры такие:
PHP код:
mysqlshow table status from phoenix like "events_original";
*************************** 
1. row ***************************
           
Nameevents_original
         Engine
MyISAM
        Version
10
     Row_format
Dynamic
           Rows
3881402
 Avg_row_length
36
    Data_length
140661920
Max_data_length
281474976710655
   Index_length
32896000
      Data_free
0
 Auto_increment
NULL
    Create_time
2006-10-25 14:30:07
    Update_time
2006-12-01 13:14:58
     Check_time
2006-12-01 13:14:58
      Collation
latin1_swedish_ci
       Checksum
NULL
 Create_options
:
        
Comment:
1 row in set (0.01 sec
эта таблица была переделана в такую:

PHP код:
'events''CREATE TABLE `events` (
  `type` tinyint(3) unsigned NOT NULL DEFAULT '
0',
  `time` int(10) unsigned NOT NULL DEFAULT '
0',
  `data` float DEFAULT NULL,
  `message` text,
  `sensor_id` int(11) NOT NULL,
  KEY `speed` (`sensor_id`,`time`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1' 
Размеры такие:
PHP код:
mysqlshow table status from phoenix like "events";
*************************** 
1. row ***************************
           
Nameevents
         Engine
MyISAM
        Version
10
     Row_format
Dynamic
           Rows
3831702
 Avg_row_length
20
    Data_length
78099568
Max_data_length
281474976710655
   Index_length
54848512
      Data_free
0
 Auto_increment
NULL
    Create_time
2006-12-01 13:31:36
    Update_time
2006-12-01 13:33:56
     Check_time
2006-12-01 13:33:56
      Collation
latin1_swedish_ci
       Checksum
NULL
 Create_options
:
        
Comment:
1 row in set (0.02 sec
Фактически вместо equipment_id (16 байт) + sensor (1 байт) был введен sensor_id (4 байт). Фактически каждая пара equipment_id @ sensor, была переиндексирована в sensor_id (4 байт для всех сенсоров с головой хватит). Соответственно изменился и ключ (раньше он был 21 байт, сейчас — 8).

Вышло, что каждой паре equipment_id + sensor сейчас отвечает sensor_id, тоесть их количество должно быть равным (тоесть сенсоры как были уникальными, так ими и остались). Время вообще не трогалось (соответственно оно и не должно играть никакой роли).

Тоесть количество уникальных 3 практически равно количеству уникальных 2.

Вот результаты SHOW KEYS:

PHP код:
mysqlshow keys from events_or;
+-----------+------------+-------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
Table     Non_unique Key_name    Seq_in_index Column_name  Collation Cardinality Sub_part Packed Null Index_type Comment |
+-----------+------------+-------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
events_or |          equipmentid |            equipment_id A         |          14 |     NULL NULL   |      | BTREE      |         |
events_or |          equipmentid |            sensor       A         |          80 |     NULL NULL   |      | BTREE      |         |
events_or |          equipmentid |            time         A         |     3881402 |     NULL NULL   |      | BTREE      |         |
+-----------+------------+-------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.00 sec)

mysqlshow keys from events;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
Table  Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
events |          speed    |            sensor_id   A         |          76 |     NULL NULL   |      | BTREE      |         |
events |          speed    |            time        A         |     3831708 |     NULL NULL   |      | BTREE      |         |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.01 sec
Вот, относительно уникальости пар:

PHP код:
mysqlselect count(DISTINCT `sensor_id`) from `events`;
+-----------------------------+
count(DISTINCT `sensor_id`) |
+-----------------------------+
|                          
76 |
+-----------------------------+
1 row in set (42.95 sec)

mysqlselect count(DISTINCT `equipment_id`,`sensor`) from `events_or`;
+-----------------------------------------+
count(DISTINCT `equipment_id`,`sensor`) |
+-----------------------------------------+
|                                      
81 |
+-----------------------------------------+
1 row in set (53.94 sec
Разница в количестве, объясняется тем что во время переиндексации были найдены events для несуществующих сенсоров (наверно остались с ранних стадий разработки). Всего было удалено 49700 events, тоесть особого влияния они оказать не могут (причем, это удаление должно было бы уменьшить индекс).

Это делалось чтобы уменьшить размер данных и индекса.

НО размер индекса вырос почти в 2 раза!!!
Почему, и как с этим боротся???

Таблица реиндексировалась (как только я увидел выросший размер, сначала сделал OPTIMIZE, потом удалил MYI и пересоздал его). Размер индекса не изменился.
mmaaxx вне форума