Запуск одного и того же запроса несколько раз с разными параметрами - PullRequest
0 голосов
/ 05 мая 2019

Мне нужно выполнить SQL-запрос на выборку из службы .net к базе данных MYSQL. Выполнение запроса занимает около 1 секунды и должно выполняться 36 раз подряд с разными датами для каждого запуска.

Простой пример запроса, где дата будет меняться для каждого выполнения:

SELECT * FROM person where date < "some date"

Я хотел бы знать, каковы мои варианты выполнения запроса, и каков мой лучший вариант с точки зрения производительности. Должен ли я запустить его 36 раз против БД? Использовать хранимую процедуру и перебирать разные даты? Любой другой вариант?

Обратите внимание, что нет возможности изменить запрос, чтобы разрешить меньшее количество выполнений, я должен выполнить его 36 раз, и я пытаюсь выяснить, каковы жизнеспособные варианты, плюсы и минусы для каждого варианта.

Edit:

Я попытаюсь сделать мой пример запроса более понятным:

Запрос состоит из нескольких операторов выбора, каждый оператор выбора производит вычисление: либо суммирование суммы, либо подсчет вхождений и т. Д. Каждый запрос зависит от даты, переданной запросу. Мне нужны результаты этих расчетов для 36 различных периодов времени.

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

В настоящее время я 36 раз выполняю запрос с моего сервера .Net к моей базе данных MYSQL. Просто кажется, что это не лучший способ сделать это. Я могу рассмотреть возможность перемещения запроса к хранимым процедурам и, возможно, выполнения одного и того же запроса в цикле 36 раз вместо вызова БД для каждого запроса. Я хотел узнать, есть ли у кого-нибудь лучшая идея для решения проблемы запуска одного и того же запроса с разными параметрами много раз.

* * Пример тысяча двадцать-один: * * 1 022
SET @id = 11111;
SET @calculations_date = "2019-05-05";
SET @calculations_date_minus_1_year = DATE_SUB(@calculations_date, INTERVAL 1 YEAR);

SELECT customers.id,
IFNULL( (SELECT COUNT(DISTINCT id) FROM customer_data WHERE id = @id AND customer_data.date >= DATE_SUB(@calculations_date, INTERVAL 2 YEAR) AND customer_data.date <= @calculations_date) , 0) as customers_in_last_24_months,
IFNULL( (SELECT SUM(amount) FROM other_customer_data WHERE id = @id AND date <= @calculations_date_minus_1_year), 0) AS total_other_customer_data_until_12_months_before_date,
IFNULL( (SELECT SUM(amount) FROM other_customer_data2 WHERE id = @id AND date <= @calculations_date_minus_1_year), 0) AS total_other_customer_data2_until_12_months_before_date,
IFNULL( (SELECT SUM(amount) FROM other_customer_data3 WHERE id = @id AND date <= @calculations_date_minus_1_year), 0) AS total_other_customer_data3_until_12_months_before_date,
FROM customers
WHERE customers.id = @id;

Спасибо!

Ответы [ 3 ]

1 голос
/ 05 мая 2019

Ну, первая коленная реакция на улучшение производительности оператора select - это введение индекса в таблицу (в вашем случае в столбец даты).Pro: быстро, легко Con: требуется больше дискового пространства (в зависимости от вида индекса и размера таблицы это может быть значительным)

Другой вариант, который мне приходит в голову, - это загрузить всю таблицу в память и выполнитьфильтрация там.Это, конечно, быстрее, но особенно для больших таблиц, которые зачастую нежизнеспособны, поскольку у вас может быть недостаточно ОЗУ.

Если есть какой-либо способ переписать запрос, вы можете выбрать для всех 36 человек одновременно,но вы заявили, что «нет возможности изменить запрос» ... так что я думаю, что эта опция отсутствует в окне?

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

Надеюсь, я смог предоставить вам некоторые варианты, которые вы можете использовать в качестве отправной точки;)

0 голосов
/ 07 мая 2019

Я решил создать запрос динамически на стороне сервера и включить UNION ALL между каждым разделом, чтобы избежать многократного доступа к БД.

0 голосов
/ 06 мая 2019

Если перед «какой-то датой» есть миллион строк, то запуск займет много времени, и ваш клиент захлебнется объемом данных. Итак, я утверждаю, что это нереальный запрос.

С другой стороны,

SELECT * FROM person where date < "some date"
    ORDER BY date  LIMIT 10

возвращает только (максимум) 10 строк. Если есть INDEX(date), то выполнение запроса будет очень быстрым и почти постоянным. Я ожидал бы миллисекунды, не 1 секунду.

При такой скорости у вас может быть 360 пользователей, делающих запрос «одновременно».

Или вы имели в виду, что одно соединение выполняет 36 SELECTs. В этом случае кажется, что они будут получать дублирующую информацию ??

Издержки - это значительная часть простых запросов. Возможно, мы можем поместить 36 запросов в один?

Кроме того, вам нужны все столбцы таблицы? Оставьте ненужные столбцы, чтобы уменьшить громоздкость трансмиссии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...