#sql #database #mariadb #load #database-performance
#sql #База данных #mariadb #загрузка #база данных-производительность
Вопрос:
В настоящее время я использую сервер Ubuntu с Mariadb на нем. Он обслуживает все sql-запросы для веб-сайта (с большим количеством запросов на нем).
Несколько раз в день мы импортируем большие CSV-файлы в базу данных для обновления наших данных. Проблема в том, что эти csv загружают базу данных (импорт занимает около 15 минут).
Кажется, что используется только 1 ядро из 4, но, тем не менее, веб-сайт (или, лучше, его запросы sql в течение этого времени) становятся смехотворно медленными. Теперь у меня вопрос: что я могу здесь сделать, чтобы повлиять на веб-сайт в меньшей степени? Я рассматривал репликацию базы данных на другой сервер, но я ожидаю, что это будет использовать такое же количество ресурсов во время импорта, так что никакой реальной пользы здесь, я думаю?
Другая вещь, которую я рассмотрел, — это иметь 2 базы данных SQL, и во время импорта все запросы должны быть переключены на другой сервер базы данных, и я бы в основном выполнял каждый импорт дважды, один на сервере 1 (в течение этого времени сервер 2 должен обслуживать сайт), как только это будет сделано, веб-сайт должен быть удаленна сервер 1, а импорт выполняется на сервере 2. Хотя это сработало бы, кажется, что это довольно сложно для неидеального решения (например, как обрабатываются запросы при переключении с сервера 1 на сервер 2 и так далее.
Итак, какие решения существуют здесь, желательно несколько доступные. Все идеи и подсказки приветствуются.
Заранее спасибо с наилучшими пожеланиями
Menax
Комментарии:
1. Что касается проблемы с 1 потоком, которая, по-видимому, решаема с помощью решения здесь, определенно собираюсь попробовать. dba.stackexchange.com/questions/5666 /…
2. «SQL Server» — это название конкурирующего продукта. Пожалуйста, не используйте его при обращении к MariaDB; это сбивает с толку.
Ответ №1:
Является ли импорт заменой всей таблицы? Если это так, загрузите его в отдельную таблицу, а затем замените ее на место. По существу нулевое время простоя, а именно во время RENAME TABLE
. Подробнее см. http://mysql.rjweb.org/doc.php/deletebig или , возможно, http://mysql.rjweb.org/doc.php/staging_table
Если импорт выполняет что-то еще, пожалуйста, предоставьте подробную информацию.
Одно соединение использует одно ядро, не более.
Подробнее (из комментариев)
SELECT id, marchants_id
from products
WHERE links LIKE '%https://´www.merchant.com/productsite_5'
limit 1
Это сложно оптимизировать из-за ведущего подстановочного знака в LIKE
. Это действительно то, что вам нужно? В нынешнем виде этот запрос должен сканировать таблицу.
SELECT id, price
from price_history
WHERE product_id = 5
order by id desc
limit 1
Это выиграло бы от INDEX(product_id, id, price)
— в таком порядке. С этим индексом запрос будет максимально приближен к мгновенному.
Пожалуйста, предоставьте оставшуюся часть транзакции с обновлением и вставкой, а также SHOW CREATE TABLE
. Вполне возможно, что есть способ «пакетного» выполнения действий, а не указывать цену одного продукта за раз. Это может ускорить работу в 10 раз.
Переключение между двумя серверами — только если данные доступны только для чтения. Если вы иным образом изменяете таблицы, это было бы большим кошмаром.
Для полной замены таблицы,….
- СОЗДАЙТЕ новую ТАБЛИЦУ
- Заполните его
- ПЕРЕИМЕНУЙТЕ ТАБЛИЦУ, чтобы заменить новую таблицу на место.
(Но я все еще недостаточно хорошо понимаю вашу обработку, чтобы сказать, лучше ли это. Когда вы говорите «переключить действующую базу данных», вы имеете в виду сервер (компьютер), БАЗУ ДАННЫХ (схему) или только одну ТАБЛИЦУ?
Комментарии:
1. Сайт в основном является своего рода сайтом сравнения цен (не на 100%, но я думаю, что это ближе всего к нему без особых объяснений) В базе данных есть таблица с ценами и ее идентификатором продукта и идентификатором поставщика Дата. Старые цены хранятся для pricehistory в другой таблице, и всякий раз, когда мы получаем обновленный csv-файл от любых поставщиков с новыми ценами, мы его импортируем. У нескольких поставщиков большинство из них имеют от 30 000 до 50 000 продуктов (в формате csv). И поскольку существуют разные продавцы, не вся таблица обменивается (обновляется) только ее частями.
2. @Menaxerius — Как вы узнаете, какие строки заменяются? (Мои предложения все еще актуальны, но «частичная» замена добавляет некоторую сложность.) И все ли обновления поступают одновременно? Или вы заменяете данные от одного поставщика за раз?
3. да, это известно (в основном все строки от этого поставщика с идентификатором поставщика), они заменяются у одного поставщика за раз. Итак, если я правильно понимаю, вы предлагаете мне импортировать их в другую таблицу, а затем переместить все записи от указанного поставщика в таблицу, где они фактически используются сайтом? Большое спасибо за ваши предложения!
4. PS: Вероятно, сработало бы сначала скопировать таблицу в другую таблицу, выполнить импорт туда, а затем переименовать таблицу, но на данный момент я еще не знаю, будет ли часть копирования менее загруженной
5. @Menaxerius — Включает ли эта «замена» удаление некоторых строк (например, товары, которые больше не продаются), вставку некоторых строк (новые товары) И обновление некоторых строк (изменения цен и т. Д.)? Или … нет новых строк? или нет удаленных строк?