Таблиця MySQL із 100 000 запитами часто запитується


11

У мене єдина база даних із близько 100 таблиць для зберігання різного роду інформації.

Найважливішою таблицею є наша таблиця замовлень, яка використовується для зберігання замовлень клієнтів і нараховує понад 100000 записів на даний момент і зростає.

Ця таблиця є найбільш запитуваною таблицею в нашій базі даних для різних частин інформації, необхідних з інформаційних панелей замовлення в режимі реального часу, статистики, аналітики тощо.

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

Я використовую такі сценарії, як 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та опублікуйте це питання
RolandoMySQLDBA

2
Я читаю це неправильно, або середній час запиту 1,7 мс? Чому б на землі ви хотіли б прискорити це?
Філ

Я трохи розгублений, чому це з’являється в журналах повільних запитів.
Шелдон

@RolandoMySQLDBA я додав схему
Шелдон

1
Тільки тому, що у вас є індекси на столі, це не означає, що вони є правильними індексами для ваших запитів. Чи можете ви опублікувати кілька прикладів повільних запитів та їх ПОЯСНЕННЯ? Також, як часто оновлюється таблиця замовлень?
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 .

Я про це писав раніше:


Дякуємо за детальне пояснення, так, індекси, додані до таблиці, базуються на запитах, що використовуються для вибору, групування та упорядкування за заявами, які використовуються в нашій системі. Проводили моніторинг запитів без журналів індексів і відповідно оновлювали таблиці.
sheldon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.