Доступ к таблицам MySQL с более чем 10 миллионами строк = Ошибка: слишком много соединений - PullRequest
1 голос
/ 13 марта 2011

Как я могу оптимизировать запросы MySQL, которые обращаются к двум таблицам с более чем 10 миллионами строк в каждой?

Что делает запрос ниже, он получает весь идентификатор из таблицы 'users', которая не выполняетсуществуют на столе гостей.В результате будет возвращено более ста тысяч строк, поэтому мы ограничиваемся, по крайней мере, получением 5000 идентификаторов за цикл.Есть ли лучший способ выполнить это, чтобы мы могли выполнить больше за один прогон.

    $before = date here before in time;
$now = date now;

$query="SELECT users.id 
    FROM users   
    LEFT JOIN guests ON guests.id = users.id    
    WHERE guests.id IS NULL AND (users.in >= '$before' AND users.in <= '$now')
    LIMIT 0,5000";

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

Если мы запустим этот процесс с обеими таблицами, содержащими более 10 миллионов строк данных, наш сервер вернет ошибку, что у него слишком много соединений и MySQLсервер больше не может быть доступен, пока вы не перезапустите его.Но если мы запустим один и тот же процесс с обеими таблицами, содержащими более нескольких тысяч строк, он не столкнется с этой проблемой, но все равно займет некоторое время.

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

Ответы [ 2 ]

1 голос
/ 13 марта 2011

2 вещи - проверьте, как ваше программное обеспечение обрабатывает соединения MySQL. Похоже, он открывает постоянное соединение, а затем не использует его повторно, и перед каждым запросом возникает новое соединение.

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

Редактировать: еще одна вещь, которую вы можете проверить, - это выполнение EXPLAIN для вашего запроса, чтобы убедиться, что у вас все правильно настроен индекс (если выбранная часть работает медленно).

0 голосов
/ 13 марта 2011

Предупреждение: протестируйте этот запрос перед запуском реальных данных.Я не несу ответственности за потерянные данные

DELETE 
  u
FROM
  users AS u 
LEFT JOIN
  guests AS g 
ON g.id = u.id
WHERE 
  g.id IS NULL 
  AND (users.in >= '$before' AND users.in <= '$now')

Что касается сути вашего вопроса (слишком много соединений), я подозреваю, что ваш PHP-скрипт запускает новые соединения в цикле для каждого идентификатора, который должен быть удален.

...