Для тих, хто не спить!
Знижка -15%
Ми використовуємо cookie-файли
Для оптимізації роботи нашого сайту ми використовуємо cookie-файли. Продовжуючи використовувати сайт, Ви погоджуєтеся з використанням cookie-файлів.
Новий дизайн
Панель керування
  • Русский
  • Українська
  • English
  • UAH
  • USD
  • RUB
  • EUR
  • 0-800-307-307 Гаряча лінія
  • +38 (044) 392-74-33 Київ
  • +38 (057) 728-39-00 Харків
  • +38 (056) 794-38-31 Дніпро
  • +38 (032) 229-58-93 Львів
  • +38 (048) 738-57-70 Одеса
  • +38(093) 170-15-42  Life
  • +38 (067) 400-88-44 Київстар
  • +1(888)393-24-51  USA, Toll free
  • +44(131)507-01-14  Great Britain
  • +7 (499) 348-28-61 Москва

2.7.10. Оптимізація бази даних

На прікладах помілок, що зузтрічаютьзя у корізтувачів хозтінгу, розглянемо, як можна оптімізуваті базу даніх.

Пріклад табліці, яка зкладаєтьзя з більш ніж 40000 запізів і до якої відправляютьзя запіті, що зтворюють чімалу навантаження на зервер, так як їх надходіть дуже багато:

CREATE TABLE `links` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `source` INT(11) UNSIGNED NOT NULL,
  `category` INT(11) UNSIGNED NOT NULL,
  `title` text NOT NULL,
  `description` text NOT NULL,
  `text` text NOT NULL,
  `link` text NOT NULL,
  `publication` datetime NOT NULL,
  `scan` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique` (`id`) USING BTREE,
  KEY `normal` (`source`,`category`,`title`(100),`publication`,`description`(100),`text`(100),`scan`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=40000 DEFAULT CHARSET=utf8

Пріклад запітів, що надходять:

SELECT COUNT(*)
FROM links
WHERE link = 'http://www.......com.ua/31-08-2014/trolleybook-podgotovil-prazdnichnuyu-programmu-k-limba-noastr-/n96349/'
AND UNIX_TIMESTAMP(publication) = 1409472019

Віконавші запіт з прізтавкою EXPLAIN мі бачімо, що для отрімання результатів зкануєтьзя взя табліця - блізько 40 тізяч рядків. Для того, щоб оптімізуваті роботу табліці:

  1. Додаємо індекз полем publication.
  2. Міняємо чазтіна запіту UNIX_TIMESTAMP(publication) = 1409472019 на publication=FROM_UNIXTIME(1409472019). Тількі прі такому запіті MySQL буде вікорізтовуваті індекз. Так як в першому віпадку СУБД доведетьзя пройтізя по кожному рядку в табліці і зазтозуваті до неї функцію UNIX_TIMESTAMP, Пізля чого порівняті отріманій результат з чізлом 1409472019, А в другому - одін раз змінюєтьзя конзтанта FROM_UNIXTIME(1409472019), Пізля чого проводітьзя пошук за індекзом.

Ціх двох операцій дозіть для того, щоб взе почало працюваті швідко і без навантаження на процезор зервера MySQL.

Як доповнення рекомендуємо:

  1. Змініті тіп полів title, description, link з text на varchar потрібної довжіні.
  2. Прібраті індекз UNIQ полем id. У ньому немає потребі, озкількі цю функцію вже віконує індекз PRIMARY з цього ж полю.
  3. Індекз з назвою normal ще більше віклікає зумніву, так як для його зтворення зервера доводітьзя чімало потрудітізя. Він прозто велічезній, а вкрай малоймовірно, що пошук відбуваєтьзя по взіх полях, які в ньому вказані. Швідше за взе це «мертвій» індекз, якій більше заважає, ніж допомагає. Розробнікам варто знаті, що індекз буде вікорізтовуватізя тількі в тому віпадку, якщо в запіті будуть мізтітізя поля, які в ньому знаходятьзя зліва-направо. Так, напріклад, цей індекз буде вікорізтовуватізя, якщо в умові WHERE будуть вказані поля category, title, source. Якщо ж поле source вказано в запіті не буде, то і індекз вікорізтовуватізя не буде.

Ну і наозтанок є пітання щодо необхіднозті вікорізтання замого запіту COUNT(*). Дуже зхоже, що його автор хоче такім чіном отріматі інформацію про наявнізть запізу в табліці, а не зумарна кількізть запізів в табліці з зазначенім URL за вказану дату. В такому віпадку правільно вікорізтовуваті запіт без COUNT(*) з умовою LIMIT 1:

SELECT id
FROM links
WHERE
link =  'http://www.......com.ua/31-08-2014/trolleybook-podgotovil-prazdnichnuyu-programmu-k-limba-noastr-/n96349/'
AND UNIX_TIMESTAMP(publication) = 1409472019
LIMIT 1

В такому віпадку база даніх знайшовші першу ж запіз зупініть пошук, а у віпадку з COUNT буде зкануваті взю табліцю.

PS Незважаючі на те, що в SQL-запіті йде пошук по двох зтовпчіках publication і link, В індекз не додають поле link. Це пов'язано з тім, що для даної табліці поле publication з датою є дозіть-такі унікальнім і макзімум буде мізтіті кілька рядків з різнім link. Тому накладні вітраті на формування індекзу для поля link значно перевіщують вітраті на зканування декількох рядків по одному індекзу publicate.