SQL

Блин что то не могу найти способ произвести эффективную выборку данных из таблицы БД?

Предположим есть таблица условно простая из 4 полей. id, nick, pass, score. Однако размер таблице составляет 10 млн записей. Работу с БД осуществляет серверное приложение на сервере а клиентские с ним взаимодействуют. Клиент может запросить 100 самых высоких по score строк а также может запросить 100 строчек также по score но относительно своей позиции. То есть в обоих случаях таблица будет прочитана вся + отсортирована + отобраны 100 строчек. Это слишком трудоемко будет для моего сервера... Как можно это все облегчить?

Пока что из идей только что передать это все на выполнение другому серверному потоку с временной задержкой скажем в 10 сек которая будет обновлять таблицы поддерживая их в отсортированном порядке. Этот вариант хоть и будет нагружать сервер, но это будет ожидаемой постоянной нагрузкой а не безконтрольной, когда множество клиентов разом запросят свои 100 строк... Что подскажете?
Размер таблицы всего-то 10 миллионов записей.
Если тебе нужно выбирать по значению scope, значит нужен индекс по столбцу scope.
И при наличии индекса запрос:
 SELECT * FROM table ORDER BY scope DESC LIMIT 100 
будет выполнен очень быстро.
Николай Козлов
Николай Козлов
94 303
Лучший ответ
Дмитрий Миронов Получается на стадии создании таблы необходимо пометить определенное поле столбца индесом, и тогда сортировка будет выполнена быстро? Ну ок. Это хорошо. А что на счет выборки не из 100 лучших и 100 худших. а где то посередине...
Вот я получаю SELECT * FROM `table` ORDER BY `score` WHERE ???
Смысл в том чтобы получить текущую строчку клиента и еще 50 лучших и 50 худших. иначе говоря 101 строчка.
Дмитрий Миронов А атрибут Unsigned также при создании таблицы пойдет на пользу или лучше не ставить?
Скажу, что если построить обычный индекс по этому полю, все должно работать быстро и хорошо. 10М записей - это ни о чем.
Я вот сейчас пытаюсь выгрузить в облако 10 миллиардов записей - это да, это задача...
Захар Прусский
Захар Прусский
60 480
Дмитрий Миронов Это радует =)) Значит вообще решение изи. Я уже боялся того что придется поток запускать.. Это вообще кустарщина была б
Дмитрий Миронов А еще такой вопрос. применительно к моей задаче. У меня 1 таблица в которой присутствует 10 параметров для индексации (10 score для 10 разных лидербордов) ну и кроме этого еще порядка 30 не индексируемых полей. Такая вот широкая таблица(так как изначально планировался всего 1 лидерборд а не 10)... В итоге я могу прямо в ней выставить по индексируемым полям индексы и обращаться к этой табле для взятия данных для любого лидерборда но с разными индексами или лучше будет все таки разбить эту таблу на 10 таблиц с единственным индексом по каждой табле?
И не найдёшь, я его съел.
Валера Фелькер
Валера Фелькер
79 197
Если таблицу часто меняют, то добавление индексов поможет только на первое время, а потом злобные тормоза постепенно придут обратно. Потому что у индексов со временем возникнет фрагментация - нужно время от времени обновлять, перестраивать. Также у них есть статистика, которая должна быть свежей, актуальной, чтобы планировщик мог строить план выбора данных адекватно.
Индексирование: Убедитесь, что ваши поля, по которым производится выборка (например, поле "score"), проиндексированы. Индексы позволяют БД быстро находить и сортировать данные, без необходимости полного сканирования таблицы. Это может значительно снизить нагрузку на сервер.

Ограничение количества записей: Вместо того чтобы выбирать и сортировать все 10 млн записей, вы можете ограничить количество записей, выбираемых из таблицы. Например, использовать оператор LIMIT в SQL-запросе, чтобы выбрать только 100 записей с самыми высокими значениями "score". Это может существенно сократить объем данных, передаваемых между сервером и клиентом.

Кэширование: Рассмотрите возможность кэширования результатов запросов на сервере. Например, вы можете кэшировать результаты 100 записей с самыми высокими значениями "score" и обновлять кэш с определенным интервалом. Это позволит избежать избыточных запросов к БД и снизить нагрузку на сервер.

Асинхронная обработка: Вместо того чтобы выполнять выборку данных сразу при запросе клиента, вы можете передавать задачу на выборку данных в асинхронный процесс на сервере. Например, вы можете использовать отдельный поток или очередь задач для обработки таких запросов с задержкой, как вы предложили. Это позволит вашему серверу более гибко управлять ресурсами и снизить риск перегрузки при множественных запросах клиентов.

Денормализация данных: Если доступность данных в реальном времени не является критически важной, вы можете рассмотреть возможность денормализации данных, то есть хранения предварительно подготовленных данных, таких как 100 записей с самыми высокими значениями "score", в отдельной таблице или кэше. Это может упростить запросы и уменьшить нагрузку на сервер.

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