2012-06-19 5 views
1

У меня есть база данных из 5 м строк, и она растет, и с ней все труднее и труднее выполнять операции.Разделение базы данных по ID пользователя

Полезно ли разбить таблицу на 10 таблиц (v0_table, v1_table ... v9_table), где число (v *) является первым числом идентификатора пользователя?

Идентификатор пользователя в моем случае не является автоматическим приращением, поэтому он будет сортировать данные равномерно по этим 10 таблицам.

Проблема не я никогда не делал подобные вещи ....

Можно ли обнаружить какие-либо недостатки?

EDIT:

Я был бы признателен за любую помощь в настройке структуры или запроса. Так медленный запрос заключается в следующем:

SELECT logos.user, 
     logos.date, 
     logos.level, 
     logos.title, 
     Count(guesses.id), 
     Sum(guesses.points) 
FROM logos 
     LEFT JOIN guesses 
       ON guesses.user = '".$user['uid']."' 
       AND guesses.done = '1' 
       AND guesses.logo = logos.id 
WHERE open = '1' 
GROUP BY level 

Где догадывается стол:

+--------+------------+------+-----+-------------------+----------------+ 
| Field | Type  | Null | Key | Default   | Extra   | 
+--------+------------+------+-----+-------------------+----------------+ 
| id  | int(11) | NO | PRI | NULL    | auto_increment | 
| logo | int(11) | NO | MUL | NULL    |    | 
| user | int(11) | NO | MUL | NULL    |    | 
| date | timestamp | NO |  | CURRENT_TIMESTAMP |    | 
| points | int(4)  | YES | MUL | 100    |    | 
| done | tinyint(1) | NO | MUL | 0     |    | 
+--------+------------+------+-----+-------------------+----------------+ 

ЛОГОС стол:

+-------+--------------+------+-----+-------------------+----------------+ 
| Field | Type   | Null | Key | Default   | Extra   | 
+-------+--------------+------+-----+-------------------+----------------+ 
| id | int(11)  | NO | PRI | NULL    | auto_increment | 
| name | varchar(100) | NO |  | NULL    |    | 
| img | varchar(222) | NO | MUL | NULL    |    | 
| level | int(3)  | NO | MUL | NULL    |    | 
| date | timestamp | NO | MUL | CURRENT_TIMESTAMP |    | 
| user | int(11)  | NO | MUL | NULL    |    | 
| open | tinyint(1) | NO | MUL | 0     |    | 
+-------+--------------+------+-----+-------------------+----------------+ 

EXPLAIN:

+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra          | 
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+ 
| 1 | SIMPLE  | logos | ref | open   | open | 1  | const | 521 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | guesses | ref | done,user,logo | user | 4  | const | 87 |            | 
+----+-------------+---------+------+----------------+------+---------+-------+------+----------------------------------------------+ 
+0

Похоже, что это сделало бы запросы ужасно запутанными. – jedwards

ответ

0

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

CREATE INDEX open_level ON logos(open, level) 

Это должно устранить Использование временных; Использование filesort на логотипах.

В принципе, вам нужен индекс по этой таблице для этого запроса, чтобы покрыть две вещи: открытых - для WHERE open = '1' и уровня - для GROUP BY level в таком порядке, так как MySQL будет первым фильтр открытого, то будет группировать результаты на уровень (неявно сортировать по нему в процессе).

+0

Не могли бы вы объяснить, что он делает и почему он содержит только «открытый» и «уровень»? –

+0

Честно говоря, этот индекс помог. Минимизированная загрузка ЦП на 20%. Спасибо :) Хотя OP был другим, но вы помогли с окончательным запросом оптимизации. –

+0

@Arturs: расширенный. – MaxSem

0

Короткий и сладкий : Нет. его никогда не бывает хорошей идеей. Правильно ли указана ваша таблица? Правильно ли настроен MySQL? Эффективны ли ваши запросы? Используете ли вы кеширование?

+0

Использование memcache, где я могу, также увеличил кеш mysql, индексированные таблицы (dunno if правильно). Проблема заключается в том, что в Интернете есть 500 пользователей, и эта таблица обновляется очень часто ... Почему это не очень хорошая идея? –

+0

Разделение таблиц по-другому может иметь смысл, но не так, как вы предложили в OP. Многие базы данных помещают «часто обновляемые» поля в таблицу отдельно от «редко обновляемого» – jedwards

+0

Это сделано. И я просто ищу дополнительного улучшения.Даже сейчас для получения 30 записей (от 5,2 м) требуется 0,3 с, когда я только в сети. Но когда 500 пользователей в сети, это дико. –

0

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

Это позволяет оптимизировать аппаратное обеспечение для небольших наборов данных.

+0

Проблема в том, что у меня есть 3 таблицы, где часто используются 2 из них. Так что третий является отдельным и часто memcached. Можете ли вы сказать мне, почему раскалывается плохая идея. –

+0

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

+0

MySQL поддерживает функцию разделения, но я не уверен, насколько хорошо она работает на практике. http://dev.mysql.com/doc/refman/5.5/ru/partitioning.html –