2015-03-15 2 views
1

Запрос:MySQL/MariaDB медленно UPDATE на PRIMARY KEY

UPDATE `cart` SET `user_id` = NULL, `completed` = 0 WHERE `id` = 6948; 
Query OK, 0 rows affected (1.21 sec) 
Rows matched: 1 Changed: 0 Warnings: 0 

0 ряды пострадавших, но потребовалось 1210ms. SELECT этой строки по id всегда принимал 0 мс. Размер стола (6 354 строки).

> show create table cart; 
CREATE TABLE `cart` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `user_id` int(11) DEFAULT NULL, 
    `completed` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'флаг, указывающий на оформление заказа из данной корзины', 
    PRIMARY KEY (`id`), 
    KEY `user_id` (`user_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=6964 DEFAULT CHARSET=utf8 

> show index from cart; 
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| cart |   0 | PRIMARY |   1 | id   | A   |  6386 |  NULL | NULL |  | BTREE  |   |    | 
| cart |   1 | user_id |   1 | user_id  | A   |  2128 |  NULL | NULL | YES | BTREE  |   |    | 
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 

Вот отрывок из show profile all для этого запроса

| Status    | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out | Messages_sent | Messages_received | Page_faults_major | Page_faults_minor | Swaps | Source_function  | Source_file | Source_line | 

| query end   | 2.502555 | 0.003000 | 0.000000 |    88 |     8 |    0|   136 |    0 |     0 |     0 |     0 |  0 | mysql_execute_command | sql_parse.cc |  5093 | 

Почему block_ops_out так inconsistant, от 0 до 400, с 0 мс ~ 2500ms ??? Как найти первопричину, чтобы она была высокой?

Версия сервера: 10.0.17-MariaDB-1 ~ wheezy. У VPS вообще нет заметной нагрузки.

UPD: добавлен статус вары после запроса:

MariaDB> flush status; UPDATE `cart` SET `user_id` = NULL, `completed` = 0 WHERE `id` = 6948; SHOW SESSION STATUS LIKE 'Handler%'; 
Query OK, 0 rows affected (0.54 sec) 

^[[A^[[BQuery OK, 0 rows affected (3.88 sec) 
Rows matched: 1 Changed: 0 Warnings: 0 

+----------------------------+-------+ 
| Variable_name    | Value | 
+----------------------------+-------+ 
| Handler_commit    | 2  | 
| Handler_delete    | 0  | 
| Handler_discover   | 0  | 
| Handler_external_lock  | 0  | 
| Handler_icp_attempts  | 0  | 
| Handler_icp_match   | 0  | 
| Handler_mrr_init   | 0  | 
| Handler_mrr_key_refills | 0  | 
| Handler_mrr_rowid_refills | 0  | 
| Handler_prepare   | 2  | 
| Handler_read_first   | 0  | 
| Handler_read_key   | 1  | 
| Handler_read_last   | 0  | 
| Handler_read_next   | 0  | 
| Handler_read_prev   | 0  | 
| Handler_read_rnd   | 0  | 
| Handler_read_rnd_deleted | 0  | 
| Handler_read_rnd_next  | 0  | 
| Handler_rollback   | 0  | 
| Handler_savepoint   | 0  | 
| Handler_savepoint_rollback | 0  | 
| Handler_tmp_update   | 0  | 
| Handler_tmp_write   | 0  | 
| Handler_update    | 1  | 
| Handler_write    | 0  | 
+----------------------------+-------+ 
25 rows in set (0.00 sec) 
+0

Мое первое предположение: вы устанавливаете 'user_id', который принадлежит индексу, поэтому индекс нужно перестроить. Но 1 сек для паршивых 6к записей является странным. Может быть, запущен запуск обновления? –

+0

@juergend Нет триггеров обновлений, как правило, нет триггеров вообще во всем db. – kakysha

+0

Пожалуйста, предоставьте 'SHOW CREATE TABLE'; это более описательно, чем 'DESCRIBE'! –

ответ

0

Проблема не в MySQL/MariaDB, а в OpenVZ и планировании ввода-вывода на сервере. После перехода на более производительные диски проблема исчезла.

0

Все, что я могу предложить пытается перенести таблицу и данные в Mysql MyISAM двигатель и выполнить тот же запрос. Возможно, вы только что нашли слабую точку MariaDB или что-то неправильно настроено или опрокинуто.

+0

MyISAM, скорее всего, будет хуже, чем InnoDB. Это связано с блокировкой таблицы MyISAM. –

+0

Эта блокировка не должна влиять на время выполнения обновления одной строки. Я просто хотел исключить возможные узкие места в этом тесте. И я думаю, я мог подойти к тому же решению. – ad4s