powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Тормозит запрос в MySQL, всего 2 join
9 сообщений из 9, страница 1 из 1
Тормозит запрос в MySQL, всего 2 join
    #39450011
ZiB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ZiB
Гость
Добрый день.
Выполняю следующий скрипт:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
INSERT INTO prod 
	select distinct
			item.id
			,item.name
			,p5.price
			,p5.rest
			,item.category_id
			,p5.manufacturer_id
			,coalesce(country.name,'')
			,coalesce(p5.packing,0)
			,coalesce(p5.storage,'')
			,p5.okp
		from item
		join p5 on p5.item_id = item.id
		left join country on country.id = p5.country_id
		where p5.price > 0;


Мне выдается ошибка:
Ошибка SQL (1104): The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay

Выполняю перед скриптом:
Код: plsql
1.
SET SQL_BIG_SELECTS=1;



В итоге скрипт выполняется за 2,5 минуты.

Создание индексов не привело к ускорению скрипта:
CREATE INDEX ix_item_id ON item (id);
CREATE INDEX ix_p5_item_id ON p5 (item_id);
CREATE INDEX ix_country_id ON country (id);
CREATE INDEX ix_p5_country_id ON p5 (country_id);

Тот же самый запрос в PostgreSQL у меня на тех же данных выполняется за миллисекунды.

В чем может быть дело?
Как мне ускорить запрос?
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450051
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZiB,

Показывайте DDL таблиц, план запроса.

Зачем в запросе distinct?
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450060
ZiB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ZiB
Гость
Я не умею всего этого делать в MySQL.
distinct нужен т.к. в item встречаются полные дубли строк.
В таблице p5 я предварительно очищаю все дубли (по полю p5.item_id, оставляю где p5.id максимальный).

Оказывается запросы из PostgreSQL вовсе не работают в MySQL.
Приходится создавать темпори таблицы )-:.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
CREATE TABLE `item` (
	`id` INT(11) NULL DEFAULT NULL,
	`name` VARCHAR(255) NULL DEFAULT NULL,
	`category_id` INT(11) NULL DEFAULT NULL,
	`p0` INT(11) NULL DEFAULT NULL,
	`p2` INT(11) NULL DEFAULT NULL
)
COLLATE='cp1251_general_ci'
ENGINE=InnoDB;

CREATE TABLE `p5` (
	`id` BIGINT(11) NULL DEFAULT NULL,
	`item_id` BIGINT(11) NULL DEFAULT NULL,
	`nds` INT(2) NULL DEFAULT NULL,
	`storage` VARCHAR(12) NULL DEFAULT NULL,
	`packing` INT(11) NULL DEFAULT NULL,
	`manufacturer_id` INT(11) NULL DEFAULT NULL,
	`country_id` INT(11) NULL DEFAULT NULL,
	`price` DECIMAL(10,0) NULL DEFAULT NULL,
	`rest` DECIMAL(10,0) NULL DEFAULT NULL,
	`sum12` DECIMAL(10,0) NULL DEFAULT NULL,
	`sum14` INT(1) NULL DEFAULT NULL,
	`okp` BIGINT(11) NULL DEFAULT NULL,
	`blue` INT(1) NULL DEFAULT NULL,
	`sum17` INT(11) NULL DEFAULT NULL,
	`sum19` INT(1) NULL DEFAULT NULL,
	`sum20` INT(5) NULL DEFAULT NULL,
	INDEX `ix_p5_country_id` (`country_id`)
)
COLLATE='cp1251_general_ci'
ENGINE=InnoDB;

CREATE TABLE `country` (
	`id` INT(11) NULL DEFAULT NULL,
	`name` VARCHAR(200) NULL DEFAULT NULL,
	INDEX `ix_country_id` (`id`)
)
COLLATE='cp1251_general_ci'
ENGINE=InnoDB;

select count(*) from country; = 197
select count(*) from p5; = 7808
select count(*) from item; = 133504

EXPLAIN select distinct
			item.id
			,item.name
			,p5.price
			,p5.rest
			,item.category_id
			,p5.manufacturer_id
			,coalesce(country.name,'')
			,coalesce(p5.packing,0)
			,coalesce(p5.storage,'')
			,p5.okp
		from item
		join p5 on p5.item_id = item.id
		left join country on country.id = p5.country_id
		where p5.price > 0;



Код: plaintext
1.
2.
3.
4.
id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	SIMPLE	p5	\0	ALL	\0	\0	\0	\0	7622	33.33	Using where; Using temporary
1	SIMPLE	country	\0	ref	ix_country_id	ix_country_id	5	gb_zibnv.p5.country_id	1	100.00	\0
1	SIMPLE	item	\0	ALL	\0	\0	\0	\0	135116	10.00	Using where; Using join buffer (Block Nested Loop)
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450061
ZiB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ZiB
Гость
Я забыл сделать CREATE INDEX ix_item_id ON item (id);
сейчас сделал и все заработало быстро!
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450062
ZiB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ZiB
Гость
Я теперь очень плохого мнения о MySQL.
Что бы удалить неиспользуемые строки в таблице oc_manufacturer
(на которые нет ссылки из таблицы oc_product)
мне приходится создавать temporary table.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
	create temporary table temp1 as (
		select oc_manufacturer.manufacturer_id as id
		from oc_manufacturer
		where oc_manufacturer.manufacturer_id not in (
			select oc_manufacturer.manufacturer_id
			from oc_manufacturer
			join oc_product on oc_product.manufacturer_id = oc_manufacturer.manufacturer_id
			group by 1
		)
	);
	delete from oc_manufacturer where oc_manufacturer.manufacturer_id in (
		select id from temp1
	);



В PostgreSQL я мог это сделать проще одним запросом:
Код: plsql
1.
2.
3.
4.
5.
6.
delete from oc_manufacturer where oc_manufacturer.manufacturer_id not in (
	select oc_manufacturer.manufacturer_id
	from oc_manufacturer
	join oc_product on oc_product.manufacturer_id = oc_manufacturer.manufacturer_id
	group by 1
);



Может я чего-то не понимаю?
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450071
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZiB,

А почему item (id) не первичный ключ?
Тогда и дублей бы не было, и JOIN работал бы быстрее.
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450073
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И, кстати, после создания индексов полезно делать ANALYZE TABLE, чтобы собрать статистику. Иногда это помогает оптимизатору MySQL выбрать более подходящий (быстрый) план.
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450074
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZiBЧто бы удалить неиспользуемые строки в таблице oc_manufacturer
(на которые нет ссылки из таблицы oc_product)Я бы написал это так:
Код: sql
1.
2.
DELETE FROM oc_manufacturer
WHERE NOT EXISTS (SELECT NULL FROM oc_product WHERE oc_product.manufacturer_id = oc_manufacturer.manufacturer_id)


Нужен индекс по oc_product.manufacturer_id
...
Рейтинг: 0 / 0
Тормозит запрос в MySQL, всего 2 join
    #39450084
ZiB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ZiB
Гость
miksoft,

спасибо, такого индекса не было. С индексом ваш вариант работает очень быстро!
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Тормозит запрос в MySQL, всего 2 join
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]