Внимание: я собираюсь использовать какой-то сильный язык. Компьютеры большие и быстрые, и они могут обрабатывать больше, чем могли бы даже десятилетие за go. Но, как вы выяснили, есть пределы. Я собираюсь указать на множество ограничений, которым вы угрожали; Я попытаюсь объяснить, почему ограничения могут быть проблемой.
Настройки
query_cache_size = 1G
ужасно. Всякий раз, когда в таблицу записывается, Q C сканирует 1 ГБ в поисках любых ссылок на эту таблицу, чтобы очистить записи в Q C. Уменьшите это до 50М. Это само по себе ускорит всю систему.
sort_buffer_size = 1G
tmp_table_size=2G
max_heap_table_size=2G
- это плохо по другой причине. Если у вас есть несколько соединений, выполняющих сложные запросы, для каждого из них может быть выделено много оперативной памяти, что приводит к потере оперативной памяти, что может привести к обмену и, возможно, сбоям. Не устанавливайте их выше, чем около 1% ОЗУ.
В общем, не изменяйте значения вслепую в my.cnf. Наиболее важным параметром является innodb_buffer_pool_size
, который должен быть больше, чем ваш набор данных, но не должен превышать 70% от доступно RAM.
загрузить все записи
Ой! Стоимость переноса всех этих данных с MySQL на PHP нетривиальна. Как только он достигнет PHP, он будет храниться в структурах, которые не предназначены для огромных объемов данных - 400030 (или 600000) строк могут занимать 1 ГБ внутри PHP; это, вероятно, уничтожило бы его «memory_limit», что привело к краху PHP. (Хорошо, просто умираю с сообщением об ошибке.) Можно увеличить этот предел, но тогда PHP может привести к нехватке памяти sh MySQL, что приведет к обмену или, возможно, исчерпанию пространства подкачки. Какой беспорядок!
OFFSET
Что касается большого OFFSET
, почему? У вас есть пользователь, пролистывающий данные? И он почти на странице 10000? Его покрывают паутины?
OFFSET
должен прочитать и перешагнуть 290580 строк в вашем примере. Это дорого.
Для способа разбивки на страницы без этих издержек см. http://mysql.rjweb.org/doc.php/pagination.
Если у вас есть программа, "просматривающая" все строки 600 КБ, 30 в то время совет для "помните, где вы остановились" в этой ссылке будет очень хорошо работать для такого использования. Он не «замедляется».
Если вы делаете что-то другое; что это?
Нумерация страниц и пробелов
Не проблема. Смотрите также: http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks, который больше ориентирован на прохождение через весь стол. Основное внимание уделяется эффективному способу продвижения 30-го ряда вперед. (Это не обязательно лучше, чем запоминание последних id
.)
Эта ссылка нацелена на DELETEing, but can easily be revised to
SELECT`.
Немного математики для сканирования таблицы из 600 строк, 30 строк за один раз:
Мои ссылки: затронуты строки 600К. Или вдвое больше, если вы смотрите вперед с LIMIT 30,1
, как предлагается во второй ссылке.
OFFSET ..., 30
должно касаться (600K / 30) * 600K / 2 строк - около 6 миллиардов row.
(Следствие: изменение 30 на 100 ускорит ваш запрос, хотя все равно будет мучительно медленным. Это не ускорит мой подход, но это уже довольно быстро.)