@khodos_dmitry

Почему 1000 запросов в БД выполняются быстрее чем 1?

Оптимизировал производительность одного сайта. Думал, что объединение тысяч запросов в один даст прирост производительности. Оказалось нет. Это повысило нагрузку на базу более чем в 10 раз.
Получается, что 1000 простых запросов выполняется быстрее, чем одни сложный?
Это нормально? Так должно быть?
Примеры запросов:
Было (на эту страницу 80% траффика):
$ex = explode(",",$row['id_categories']);
foreach ($ex as $x)
{
	$res2 = $db->query("SELECT * FROM categories WHERE id='$x'");
	$row2 = $res2->fetch_array();	
}

Стало:
$categories = $db->query("SELECT `url_category`, `rus_category` FROM categories WHERE id IN ({$row['id_categories']})")->fetch_all(MYSQLI_ASSOC);


Было (таких страниц 10-ки, они забирают остальные 20% трафика ):
$res = $db->query("SELECT * FROM products
						LEFT JOIN streets ON streets.id=products.id_street
						WHERE products.id='$p'");
	$row = $res->fetch_array();
	if ($row[14] != 0) $x += $row[14];
	if ($row[15] != 0) $y += $row[15];

	$ex = explode(",",$row['id_categories']);
	$z = array();
	foreach ($ex as $o)
	{
		$res2 = $db->query("SELECT * FROM categories WHERE id='$o'");
		$row2 = $res2->fetch_array();	
		array_push($z,$row2[1]);
	}	
	$cats = implode(", ",$z);
	
	$rating = 0;
	$w = 0;
	$star_block = "";
	$resx = $db->query("SELECT * FROM products_reviews WHERE type='$row[url_product]'");
}


Стало:
$query = "SELECT products.url_product, 
products.rus_product,
products.home,
products.phone,
products.cx,
products.cy,
streets.rus_street, 
streets.url_street, 
(SELECT GROUP_CONCAT(CONCAT('<a href=\"/$url_punkt/', `url_category`, '/\">', `rus_category`, '</a>')) FROM `categories` WHERE `id` IN (SELECT `category_id` FROM `category_product` WHERE `product_id` = `products`.`id`) GROUP BY '') AS categories, 
(SELECT AVG(`rating`) FROM products_reviews WHERE type = products.url_product) as rating
FROM products 
LEFT JOIN streets ON streets.id=products.id_street
WHERE products.id_punkt = $id_punkt 
AND `products`.`id` IN (SELECT `product_id` FROM `category_product` WHERE `category_id` = $id_category)";
$products = $db->query($query)->fetch_all(MYSQLI_ASSOC);
  • Вопрос задан
  • 327 просмотров
Решения вопроса 1
@khodos_dmitry Автор вопроса
Дело было в не поставленных индексах на несколько полей.
5fa7bb154f3b1341771989.png
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
SELECT `p`.`url_product`, `p`.`rus_product`, `p`.`home`, `p`.`phone`,
       `p`.`cx`, `p`.`cy`, `s`.`rus_street`, `s`.`url_street`,
       `c`.`categories`, `r`.`rating`
  FROM `products` AS `p`
  LEFT JOIN `streets` ON `s`.`id` = `p`.`id_street`
  LEFT JOIN (
    SELECT `p`.`id` AS `product_id`, GROUP_CONCAT(CONCAT('<a href=\"/$url_punkt/', `c`.`url_category`, '/\">', `rus_category`, '</a>')) AS `categories`
      FROM `products` AS `p`
      JOIN `categories` AS `c`  ON `c`.`product_id` = `p`.`id`
      WHERE `p`.`id_punkt` = :id_punkt
        AND `p`.`id` IN (
          SELECT `product_id`
            FROM `category_product`
            WHERE `category_id` = :id_category
        )
      GROUP BY `p`.`id`
  ) AS `c` ON `c`.`product_id` = `p`.`id`
  LEFT JOIN (
    SELECT `p`.`url_product` AS `url_product`, AVG(`pr`.`rating`) AS `rating`
      FROM `products` AS `p`
      JOIN `products_reviews` AS `pr`
        ON `pr`.`type` = `p`.`url_product`
      WHERE `p`.`id_punkt` = :id_punkt
        AND `p`.`id` IN (
          SELECT `product_id`
            FROM `category_product`
            WHERE `category_id` = :id_category
        ) 
      GROUP BY `p`.`url_product`
  ) AS `r` ON `r`.`url_product` = `p`.`url_product`
  WHERE `p`.`id_punkt` = :id_punkt 
    AND `p`.`id` IN (
      SELECT `product_id`
        FROM `category_product`
        WHERE `category_id` = :id_category
    )
Ответ написан
@402d
начинал с бейсика на УКНЦ в 1988
mysql query cache
В первом случае у Вас запросы вынимались из него.
во втором случае, запрос получается каждый раз разный (зависит от товаров и их порядка на странице)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы