Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как можно ускорить запрос? / 25 сообщений из 27, страница 1 из 2
28.11.2014, 09:52:34
    #38819058
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Запрос выполняется от 1,5 до 3-х секунд, можно как-нибудь ускорить?
Код: sql
1.
2.
3.
SELECT id
FROM products_price 
WHERE round_price(price * currency_rate(cid)) BETWEEN 100 AND 20000




Код: sql
1.
2.
3.
EXPLAIN
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	prf_vdp_store_products_price	ALL	NULL	NULL	NULL	NULL	10963	Using where




Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE DEFINER=`root`@`localhost` FUNCTION `currency_rate`(`cid` INT)
	RETURNS DOUBLE
	LANGUAGE SQL
	NOT DETERMINISTIC
	CONTAINS SQL
	SQL SECURITY DEFINER
	COMMENT ''
BEGIN
SET @convert_cid = (SELECT value FROM configure WHERE `var_name` = '_currency_id' LIMIT 1);
RETURN 
(SELECT rate FROM currency_rate WHERE 
	main_cid = cid 
	AND convert_cid = @convert_cid
);
END



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE DEFINER=`root`@`localhost` FUNCTION `round_price`(`price` DOUBLE)
	RETURNS double
	LANGUAGE SQL
	NOT DETERMINISTIC
	CONTAINS SQL
	SQL SECURITY DEFINER
	COMMENT ''
BEGIN
SET @cid = (SELECT `value` FROM configure WHERE `var_name` = '_currency_id' LIMIT 1);
SET @precision = (SELECT `round_precision` FROM currency WHERE `id` = @cid LIMIT 1);
SET @coeff = POW(10,@precision);
RETURN CEIL(price*@coeff)/@coeff;
END
...
Рейтинг: 0 / 0
28.11.2014, 10:03:06
    #38819075
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983,

покажите DDL таблицы
...
Рейтинг: 0 / 0
28.11.2014, 10:06:44
    #38819082
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Как можно ускорить, если тут гарантировано полное сканирование? Пока не откажетесь от пользовательских функций, ничего не сделаете. Изложите логику происходящего и DDL исходного материала.
...
Рейтинг: 0 / 0
28.11.2014, 10:10:01
    #38819086
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoft,

Я правильно понял, это надо показать?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE `products_price` (
	`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT 'Product ID',
	`pgid` INT(10) NOT NULL COMMENT 'Product Group ID',
	`cid` INT(10) NULL DEFAULT '1' COMMENT 'Currency ID',
	`supplier_id` INT(10) NULL DEFAULT NULL COMMENT 'Supplier ID',
	`date` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Date set',
	`price` DECIMAL(15,2) NULL DEFAULT '0.00' COMMENT 'Price',
	PRIMARY KEY (`id`),
	INDEX `pgid` (`pgid`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
AUTO_INCREMENT=10964;
...
Рейтинг: 0 / 0
28.11.2014, 10:14:05
    #38819093
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Akina,

Цена в таблице price может быть в любой валюте, выводить необходимо только в одной (по курсу).
например, цены вбиты в долларах и в рублях, а фильтр в рублях. мне надо выбрать все идэшки соответсвующие условию.
как-то так.
...
Рейтинг: 0 / 0
28.11.2014, 10:34:30
    #38819125
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983
Код: sql
1.
2.
3.
CREATE DEFINER=`root`@`localhost` FUNCTION `round_price`(`price` DOUBLE)
...
SET @cid = (SELECT `value` FROM configure WHERE `var_name` = '_currency_id' LIMIT 1);

Для чего эта строка?
...
Рейтинг: 0 / 0
28.11.2014, 10:39:30
    #38819136
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoft,

Выбирает ID валюты в базе, в которой нужно все отображать, это для вычисления rate (курса) по отношению к валюте которая записана в `cid` INT(10) NULL DEFAULT '1' COMMENT 'Currency ID',
...
Рейтинг: 0 / 0
28.11.2014, 10:40:41
    #38819137
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
А стоп, это в другой функции
Там она нужна для определения количества знаков для округления
...
Рейтинг: 0 / 0
28.11.2014, 10:50:40
    #38819153
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983Там она нужна для определения количества знаков для округленияСорри, просмотрел.


Сколько всего записей в таблице и сколько выдается в результате этого запроса?
...
Рейтинг: 0 / 0
28.11.2014, 10:57:09
    #38819167
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoft,

Всего 10963

Выдаётся по разному, время выполнения от этого не меняется, даже если выводятся все записи, или если одна
...
Рейтинг: 0 / 0
28.11.2014, 11:02:26
    #38819173
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
AkinaКак можно ускорить, если тут гарантировано полное сканирование? Пока не откажетесь от пользовательских функций, ничего не сделаете.Функции еще как-то можно победить, вывернуть их наоборот в правую сторону. А вот с произведением не вижу что можно сделать...

Остается только мелочь, хотя и она может помочь:
а) Заменить вызов двух функций на один с двумя параметрами.
б) строки
Код: sql
1.
2.
3.
SET @cid = (SELECT `value` FROM configure WHERE `var_name` = '_currency_id' LIMIT 1);
SET @precision = (SELECT `round_precision` FROM currency WHERE `id` = @cid LIMIT 1);
SET @coeff = POW(10,@precision);

вынести вообще перед запросом и вызывать один раз, а не десять-двадцать тысяч раз.
...
Рейтинг: 0 / 0
28.11.2014, 11:03:04
    #38819176
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983Выдаётся по разномуЭто как это "по-разному" ? самопроизвольно?
...
Рейтинг: 0 / 0
28.11.2014, 11:07:32
    #38819185
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoft,

Код: sql
1.
2.
...BETWEEN 100 AND 20000
/*Return 5000 Row*/




Код: sql
1.
2.
...BETWEEN 19000 AND 20000
/*Return 50 Row*/
...
Рейтинг: 0 / 0
28.11.2014, 11:10:37
    #38819188
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoft
Код: sql
1.
2.
3.
SET @cid = (SELECT `value` FROM configure WHERE `var_name` = '_currency_id' LIMIT 1);
SET @precision = (SELECT `round_precision` FROM currency WHERE `id` = @cid LIMIT 1);
SET @coeff = POW(10,@precision);

вынести вообще перед запросом и вызывать один раз, а не десять-двадцать тысяч раз.


Как это можно сделать, куда их вынести?
...
Рейтинг: 0 / 0
28.11.2014, 11:11:00
    #38819189
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983,

В случае, когда возвращается полтаблицы, индексы вообще смысла не имеют. Т.е. ускорение можно получить только разве что за счет того, о чем я выше писал.

В случае, когда возвращается малая доля таблицы, можно побороться за индексный доступ, но придется модифицировать таблицу.
...
Рейтинг: 0 / 0
28.11.2014, 11:11:52
    #38819192
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983miksoft
Код: sql
1.
2.
3.
SET @cid = (SELECT `value` FROM configure WHERE `var_name` = '_currency_id' LIMIT 1);
SET @precision = (SELECT `round_precision` FROM currency WHERE `id` = @cid LIMIT 1);
SET @coeff = POW(10,@precision);


вынести вообще перед запросом и вызывать один раз, а не десять-двадцать тысяч раз.


Как это можно сделать, куда их вынести?Например, выполнять как отдельные запросы из приложения.
...
Рейтинг: 0 / 0
28.11.2014, 11:12:22
    #38819194
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoft,
понятно
...
Рейтинг: 0 / 0
28.11.2014, 11:26:04
    #38819231
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Главное, чтобы эти вызовы были строго в той же MySQL-сессии, что и основной запрос. Иначе результат будет неопределенным.
...
Рейтинг: 0 / 0
28.11.2014, 11:26:18
    #38819233
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983Цена в таблице price может быть в любой валюте, выводить необходимо только в одной (по курсу).
например, цены вбиты в долларах и в рублях, а фильтр в рублях. мне надо выбрать все идэшки соответсвующие условию.
Нафига тебе их ВЫБИРАТЬ? код валюты в таблице тебе известен, код валюты фильтра тоже, этого достаточно для выбора необходимой строки таблицы конвертации.
...
Рейтинг: 0 / 0
28.11.2014, 11:40:37
    #38819262
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Akinadeadly1983Цена в таблице price может быть в любой валюте, выводить необходимо только в одной (по курсу).
например, цены вбиты в долларах и в рублях, а фильтр в рублях. мне надо выбрать все идэшки соответсвующие условию.
Нафига тебе их ВЫБИРАТЬ? код валюты в таблице тебе известен, код валюты фильтра тоже, этого достаточно для выбора необходимой строки таблицы конвертации.

Ну если только округление вообще убрать , то уже то что надо, спасибо.
Код: sql
1.
2.
3.
4.
SELECT pr.id
FROM products_price AS pr
LEFT JOIN currency_rate AS cur ON main_cid = pr.cid AND convert_cid = 2
WHERE price * cur.rate BETWEEN 20 AND 20000



Что можно с округлением придумать?
...
Рейтинг: 0 / 0
28.11.2014, 11:42:58
    #38819268
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
И что лучше везде убрать функцию и через LEFT сделать, или только в проблемных местах?
...
Рейтинг: 0 / 0
28.11.2014, 11:46:58
    #38819280
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Код: sql
1.
2.
3.
4.
5.
SELECT pr.id
FROM products_price AS pr
LEFT JOIN currency_rate AS cur ON cur.main_cid = pr.cid AND convert_cid = 2
LEFT JOIN currency AS c ON c.id = cur.convert_cid
WHERE CEIL(price * cur.rate*POW(10,c.round_precision))/POW(10,c.round_precision) BETWEEN 20 AND 20000



Запрос не красивый, но быстрый.
...
Рейтинг: 0 / 0
28.11.2014, 11:52:25
    #38819287
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
deadly1983Запрос не красивый, но быстрый.И не совсем эквивалентный исходному.
Ведь зачем-то в функциях понатыкан везде LIMIT 1 ?
...
Рейтинг: 0 / 0
28.11.2014, 12:29:32
    #38819352
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
miksoftВедь зачем-то в функциях понатыкан везде LIMIT 1 ?Да от неграмотности. LIMIT без ORDER BY - дурь полная, причём для любого из 4 возможных вариантов.
...
Рейтинг: 0 / 0
28.11.2014, 12:33:04
    #38819361
deadly1983
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно ускорить запрос?
Akina,
так точно
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как можно ускорить запрос? / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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