MySQL таблица с 100 000 записей часто запрашивается


11

У меня есть единственная база данных около 100 таблиц для хранения различных видов информации.

Самая важная таблица - это наша таблица заказов, которая используется для хранения заказов клиентов и насчитывает более 100 000 записей на данный момент и продолжает расти.

Эта таблица является самой запрашиваемой таблицей в нашей базе данных для различной части информации, необходимой из панелей заказов в реальном времени, статистики, аналитики и т. Д.

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

Я использую такие скрипты, как mysqltuner, чтобы ежедневно выплевывать запросы.

Я также использую mysqlsla для сбора информации о 10 самых медленных запросах в нашей базе данных.

sample stat
Count         : 11.48k  (30.66%)
Time          : 19.623758 s total, 1.709 ms avg, 239 µs to 2.475017 s max  (18.64%)
  95% of Time : 5.246833 s total, 481 µs avg, 239 µs to 1.095 ms max
Lock Time (s) : 14.460071 s total, 1.259 ms avg, 53 µs to 2.462555 s max  (41.38%)
  95% of Lock : 806.43 ms total, 74 µs avg, 53 µs to 137 µs max
Rows sent     : 1 avg, 0 to 9 max  (0.99%)
Rows examined : 6 avg, 1 to 28 max  (0.15%)

Большинство самых медленных запросов включают таблицу заказов, упомянутую выше. Я использую MyISAM в качестве механизма хранения, поэтому возможны следующие проблемы:

  1. Блокировка стола
  2. Проблемы с индексированием

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

Схема таблицы

`orderid` int(11) NOT NULL AUTO_INCREMENT,
`cityid` tinyint(3) unsigned NOT NULL DEFAULT '1',
 `model_type` tinyint(1) unsigned DEFAULT '1',
`userid` int(11) DEFAULT NULL,
`usertype` char(1) DEFAULT NULL,
`time` time DEFAULT NULL,
`ordercode` char(8) DEFAULT NULL,
`restid` smallint(3) unsigned NOT NULL,
`areaid` smallint(3) unsigned DEFAULT NULL,
`restname` varchar(50) DEFAULT NULL,
`date` date NOT NULL,
`del_time` time NOT NULL,
`status` tinyint(3) unsigned NOT NULL,
`amount` float NOT NULL,
`deliverycharge` smallint(4) unsigned DEFAULT '0',
`tax` float NOT NULL,
`total` float NOT NULL,
`extras` varchar(255) DEFAULT NULL,
`requests` varchar(255) DEFAULT NULL,
`discount` float DEFAULT NULL,
`rdiscount` float DEFAULT NULL,
`reason` varchar(255) DEFAULT NULL,
`rest_order` tinyint(1) unsigned DEFAULT NULL,
`admin_user` varchar(25) DEFAULT NULL,
`mode` char(1) NOT NULL,
`priority_order` tinyint(1) unsigned DEFAULT '0',
`payment_mode` tinyint(1) unsigned DEFAULT '0',
`km` tinyint(3) unsigned DEFAULT NULL,
`order_type` tinyint(1) NOT NULL DEFAULT '1',
`coupon_discount` smallint(3) DEFAULT '0',
`pickup_time` time NOT NULL,
PRIMARY KEY (`orderid`),
KEY `cityid` (`cityid`),
KEY `date_3` (`date`,`status`,`mode`),
KEY `orderid` (`orderid`),
KEY `time` (`time`),
KEY `userid` (`userid`,`usertype`),
KEY `restid` (`restid`,`date`,`status`)

медленный лог-запрос

SELECT `a`.`orderid`, `a`.`date`, `a`.`status`, `a`.`restname`, `a`.`admin_user`, `a`.`model_type`, `b`.`name` as cityname
FROM `tk_order_queue` AS a
INNER JOIN `tk_cities` AS b ON `a`.`cityid` = `b`.`id`
WHERE `a`.`date` =  '2012-06-30'
AND `a`.`status` =  0
AND `a`.`mode` =  1
ORDER BY `a`.`orderid` desc;

Пожалуйста, запустите SHOW CREATE TABLE orders\Gи
опубликуйте

2
Я неправильно читаю или среднее время запроса составляет 1,7 мс? С какой стати вы хотите ускорить это?
Philᵀᴹ

Я немного запутался, почему это появляется в медленных журналах запросов.
Шелдон

@RolandoMySQLDBA Я прикрепил схему
Шелдон

1
То, что у вас есть индексы в таблице, не означает, что они являются правильными индексами для ваших запросов. Не могли бы вы опубликовать несколько примеров медленных запросов и их вывод EXPLAIN? Кроме того, как часто обновляется таблица заказов?
bobwienholt

Ответы:


8

Вам нужно будет сравнить предложения WHERE и операторы GROUP BY и ORDER BY всех ваших запросов, чтобы убедиться, что ваши текущие индексы могут поддерживать их в своих планах EXPLAIN.

Вчера я ответил на этот вопрос: InnoDB против MyISAM со многими индексами

В этом вопросе я предложил сделать что-то с таблицей MyISAM, что вы также можете сделать

ALTER TABLE orders ROW_FORMAT=Fixed;

Это будет рассматривать все VARCHAR как CHAR. Каждый ряд будет одинаковой длины. Это увеличит дисковое пространство на 80% -100%. Ваша таблица увеличится до максимального размера для разметки строк, умноженной на количество строк. Ваш стол может увеличиться в два или три раза.

Где выгода? Ваша таблица MyISAM будет затем считываться / записываться в любом месте на 20% - 30% быстрее, без каких-либо изменений.

Я узнал об этом на страницах 72, 73 из MySQL Database Design and Tuning .

Я писал об этом в прошлом:


Спасибо за подробное объяснение, да, индексы, добавленные в таблицу, основаны на запросах, используемых для операторов select, group by и order by, используемых в нашей системе. Контролировал запросы без логов индексов и соответственно обновлял таблицы.
Шелдон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.