Ми використовуємо 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.11. Оптимізація запитів до бази даних

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

Наприклад є запит:

SELECT 
   p.product_id, 
  (SELECT AVG(rating) AS total FROM mc_review r1 WHERE r1.product_id = p.product_id AND r1.STATUS ='1' GROUP BY r1.product_id) AS rating 
FROM mc_product p 
LEFT JOIN mc_product_description pd ON (p.product_id = pd.product_id) 
LEFT JOIN mc_product_to_store p2s ON (p.product_id = p2s.product_id) 
WHERE 
   pd.language_id = '2' AND 
   p.STATUS = '1' AND 
   p.date_available <= NOW() AND 
   p2s.store_id = '0' AND 
   p.product_id IN (SELECT pt.product_id FROM mc_product_tag pt WHERE pt.language_id = '2' AND LOWER(pt.tag) LIKE '% Роксолана%') 
ORDER BY rating ASC 
LIMIT 0,20

Якщо запит виконати з умовою EXPLAIN на початку, то отримаємо схему виконання запиту:

Тип вибірки Таблиця Тип Можливі ключі Ключ Довжина ключа Посилання Рядки Доп. інформація
PRIMARY p ALL PRIMARY 2907 Using where;
Using filesort
PRIMARY pd eq_ref PRIMARY PRIMARY 8 mebelnyc_db.p.product_id, const 1 Using where;
Using index
PRIMARY p2s eq_ref PRIMARY PRIMARY 8 mebelnyc_db.p.product_id, const 1 Using where;
Using index
DEPENDENT SUBQUERY pt ALL 6803 Using where
DEPENDENT SUBQUERY r1 ref product_id product_id 4 mebelnyc_db.p.product_id 1 Using where
  1. Якщо прибрати з цього запиту умова LIMIT, То він поверне 2907 записів. Саме 2907 раз буде виконаний вкладений в умова SELECT запит. Якщо цю частину запиту винести в окремий запит, то це зменшить навантаження на базу даних в 2907/20 = 145 раз. Хоча, судячи з назви запиту, можна зробити висновок щодо того, що таким цікавим способом автор програми намагається при кожному заході відвідувача на сайт підрахункам товарів, яка може перераховуватися, наприклад, раз на добу або ще краще - при додаванні відкликання до товару і додаватися в окрему колонку таблиці mc_product, Що дозволить позбутися від цього вкладеного запиту.
  2. В умови WHERE ми бачимо вкладений запит, який виконується в умови IN. Якби автор програми в умови IN вказав неправдиві вкладений запит, а просто статичні значення, наприклад IN (121, 1235, 43554), То MySQL використовував би індекс і відпрацював швидко. Але з вкладеними запитами справа йде зовсім по іншому - MySQL виконує їх без використання індексів, а точніше так - FIN_IN_SET(p.product_id, '121,1235,43554'). У таких випадках потрібно писати запит окремо, а потім підставляти результат його виконання в умова IN.