Оптимизация запросов с использованием первичного ключа - PullRequest
1 голос
/ 02 октября 2011

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

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

Я сохраняю каждый уникальный идентификатор для каждой игры для каждого пользователя, разделенный знаком «:». Затем я разделяю этот список и делаю отдельный запрос на КАЖДЫЙ идентификатор игры. Поэтому мой вопрос заключается в том, является ли более эффективным выполнение отдельного запроса с использованием первичного идентификатора для каждой отдельной игры или лучше просто выполнить «ВЫБОР * ИЗ игр, ГДЕ userID = 'theUsersID'».

Чтобы выразить это в более общей форме, лучше ли в долгосрочной перспективе делать несколько запросов к нескольким уникальным идентификаторам или делать один запрос, но при этом нужно просматривать каждую запись в базе данных? Просто чтобы дать представление о загрузке моей базы данных, у меня обычно 10 000 пользователей, в каждом из которых по 10 игр одновременно. Таким образом, сравнение составляет 100 000 запросов, использующих первичный ключ для каждого запроса, или 10 000 запросов, но при этом необходимо пройти все строки для каждого запроса.

Спасибо.

Ответы [ 6 ]

3 голосов
/ 02 октября 2011

MySQL даже не пропустит ритм с низкой громкостью, которую вы рассматриваете. Позвольте будущей гибкости. Ваша таблица "игры на пользователя" должна быть UniqueID, UserID, GameID --- плюс что-либо еще, что вы можете отслеживать на пользователя, на комбинацию игр ... что чаще всего происходит, когда в последний раз играли для конкретной игры и т. Д. Я НИКОГДА не рекомендовал бы объединять уникальные игры любым разделителем. Таким образом, вы можете легко запросить ...

Кто любит определенную игру, запрашивая идентификатор игры или сколько отдельных игр любит играть средний человек ... Какие игры наиболее популярны среди пользователей.

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

2 голосов
/ 02 октября 2011

Итак, насколько я понимаю, между Пользователями и Играми существует отношение многих ко многим.

Каждый пользователь играет во многие игры Каждая игра имеет много пользователей.

и вы в настоящее время сохраняете игры, в которые играют все пользователи, в таблице пользователей

User ID | Games ID's
1 | 45:23:12
2 | 23:66:11

То есть ваши таблицы не нормализованы. Даже 1NF. Подумайте о нормализации ваших данных.

Один стол для игр, который у вас уже есть. Одна таблица для пользователей, у вас есть это тоже. One Glue Table, users_games, с:

ID | userID | GameID
1 | 1 | 45
2 | 1 | 23
3 | 1 | 12
4 | 2 | 23
5 | 2 | 66
6 | 2 | 11

Таким образом, для получения данных об одном пользователе вы будете использовать Joins

Select GameID from users u join users_games ug on u.id=ug.userID where u.id='2';

и вы можете расширить столбцы в таблице users_games.

Эта модель будет масштабируемой и более управляемой.

Надеюсь, это имеет смысл:)

2 голосов
/ 02 октября 2011

Когда вы делаете "SELECT * FROM games WHERE userID = 'theUsersID'", ядру базы данных не нужно фактически искать ВСЕ записи базы данных.

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

0 голосов
/ 02 октября 2011

Выполнение одного большого запроса вместо множества маленьких обычно предпочтительнее, потому что:

  • Это может быть выполнено за один прием в обе стороны базы данных вместо многих.Это особенно важно, когда обходы базы данных должны проходить по сети.
  • Позволяет ядру базы данных использовать более сложный план запросов, чем простые NESTED LOOPS, которые вы эмулируете в своем коде («большие» базы данных, такие как Oracleтакже способны выполнять MERGE или HASH JOIN, не уверен насчет MySQL).

Выполнение JOIN на ваших двух таблицах должно помочь.

0 голосов
/ 02 октября 2011

Насколько я понимаю, ваши таблицы построены так:

Table_User:
UserId (PK);
UserInformation;
UserInformation2; 
...

Table_Games:
GameId (PK);
UserId (PK);
GameInformation;
...

Итак, сделаем LEFT-Join:

SELECT * 
FROM Table_Games G 
LEFT JOIN Table_User U on (U.UserId = G.UserId) 
WHERE UserId = 'MyUserId'

может вам помочь.

Здесь вы также можете ВЫБЕРИТЕ пользователя по уникальному имени или кому-либо еще. еще на основе Table_User!

Привет!

0 голосов
/ 02 октября 2011

SELECT * FROM игр, ГДЕ userID = userID будет лучшей моделью;

, если вам нужно соединить несколько игр с одним пользователем, используйте LEFT JOIN, так что вы сможете сделать это одним запросом

в игровой таблице есть следующие столбцы id |userID |на id поставить уникальный AI и userID может быть просто index

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