Проблема с производительностью в MySQL 5.6 - PullRequest
1 голос
/ 02 мая 2019

У меня серьезная проблема с производительностью при вставке, выделении и обновлении строк в таблице в mysql.

Структура таблицы Я использую это

CREATE TABLE `sessions` (
     `sessionid` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
     `expiry` datetime NOT NULL,
     `value` text NOT NULL,
     `data` text,
     PRIMARY KEY (`sessionid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Sessions';

запросов , с которыми я сталкиваюсь проблемы :

INSERT INTO sessions (SESSIONID, EXPIRY, DATA, VALUE) VALUES ('b8c10810c505ba170dd9403072b310ed', '2019-05-01 17:25:50', 'PFJlc3BvbnNlIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM', '7bKDofc/pyFSQhm7QE5jb6951Ahg6Sk8OCVZI7AcbUPb4jZpHdrCAKuCPupJO14DNY3jULxKppLadGlpsKBifiJavZ/');

UPDATE sessions SET EXPIRY = '2019-05-01 17:26:07' WHERE (SESSIONID = 'e99a0889437448091a06a43a44d0f170');

SELECT SESSIONID, EXPIRY, DATA, VALUE FROM sessions WHERE (SESSIONID = '507a752c48fc9cc3043a3dbe889c52eb');

Я попытался объяснить запрос, но не смог сделать вывод об оптимизации таблицы / запроса.

Из отчета с медленным запросом занято время

для выбора в среднем составляет 23,45, для обновления - 15,93, а для вставки - 22,31.

Любая помощь в выявлении проблемы очень ценится.

Ответы [ 2 ]

1 голос
/ 03 мая 2019

Сколько запросов в секунду?

Насколько велика таблица?

Сколько оперативной памяти?

Какое значение innodb_buffer_pool_size?

UUID ужасны для производительности.(Это SHA1?) Это потому, что они настолько случайны, что «следующий» запрос (любой из тех, что вы упомянули), скорее всего, не находится в кеше, поэтому требуется обращение к диску.

Итак, стаблица, которая намного больше, чем buffer_pool, вы не сможете поддерживать более 100 запросов в секунду с помощью вращающегося диска.SSD будет быстрее.

Подробнее о пороках UUID (SHA1 обладает такими же прискорбными свойствами, но не имеет решения, подобного тому, что для uuids): http://mysql.rjweb.org/doc.php/uuid

Одна небольшая вещь, которую вы можете сделатьдля сокращения таблицы:

session_id BINARY(20)

и использование UNHEX() при вставке / обновлении / удалении и HEX() при выборе.

Подробнее

51KB avg row len -> Столбцы TEXT большие и «вне записи», поэтому для работы со строкой требуется несколько блоков.

0.8GB buffer_pool, но 20 ГБ данных и'random' PRIMARY KEY -> Кэш практически бесполезен.

Это означает, что будет несколько дисков обращений для каждого запроса, но, вероятно, под10.

300 мс (быстрое время) -> около 30 обращений к диску на жестком диске (больше на SSD; что у вас есть?).

Итак, я должен предположить, что 20 с длязапрос произошел, когда произошел всплеск активности, когда запросы были запутаны друг в друге, что привело к большому количеству конфликтов ввода-вывода.

Что делать?Большая часть данных выглядит как шестнадцатеричная.Если это так, вы могли бы сократить площадь диска в два раза (и сократить некоторые при необходимости попадания на диск), упаковав и используя BINARY(..) или BLOB.

INSERT INTO sessions (SESSIONID, EXPIRY, DATA, VALUE)
    VALUES (UNHEX('b8c10810c505ba170dd9403072b310ed'),
            '2019-05-01 17:25:50',
            UNHEX('PFJlc3BvbnNlIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM'),
            UNHEX('7bKDofc/pyFSQhm7QE5jb6951Ahg6Sk8OCVZI7AcbUPb4jZpHdrCAKuCPupJO14DNY3jULxKppLadGlpsKBifiJavZ/'));

UPDATE sessions SET EXPIRY = '2019-05-01 17:26:07'
 WHERE SESSIONID = UNHEX('e99a0889437448091a06a43a44d0f170');

SELECT SESSIONID, EXPIRY, DATA, VALUE FROM sessions
 WHERE SESSIONID = UNHEX('507a752c48fc9cc3043a3dbe889c52eb');

и

 `sessionid` VARBINARY(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
 `expiry` datetime NOT NULL,
 `value` BLOB NOT NULL,
 `data` BLOB,

И ROW_FORMAT=DYNAMIC может быть оптимальным (но это не критично).

0 голосов
/ 02 мая 2019

Ваши запросы выглядят хорошо, но проблема в вашем сервере, возможно, у него недостаточно памяти для обработки такого запроса, вы можете увеличить память вашего сервера базы данных, чтобы получить оптимизированный ответ

execution of same queries

...