MySQL - структура таблицы

12
sidorka
На сайте с 17.08.2012
Offline
211
1103

Приветствую.

Какая структура предпочтительней при большом количестве записей и частом обновлении?

1. Все в одной таблице с кучей полей с индексами.

2. Данные по разным таблицам, выборка по ним + join

?

Записей >100 лямов. При UPDATE и INSERT диск грузится - я так понимаю, из-за того, что индексы пересчитываются. Индексов около десяти - и простые, и составные. На чтение работает шустро. Ускорят ли отдельные таблицы операции обновления и вставки?

---------- Добавлено 08.11.2015 в 12:24 ----------

И еще вопрос вдогонку.

SELECT ... FROM t1 JOIN t2 USING (id) JOIN t3 USING (id) WHERE t1.f1=value1 AND t2.f2=value2 AND t3.f3=value3 ORDER BY t2.f4

Индексы по полям во WHERE и ORDER будут работать? Как правильно индексы тут организовать?

Дешевые домены для дорвеев и не только - от 55р (https://goo.gl/Wtnwqp)
B
На сайте с 23.05.2001
Offline
195
#1
sidorka:
Приветствую.

Какая структура предпочтительней при большом количестве записей и частом обновлении?

1. Все в одной таблице с кучей полей с индексами.
2. Данные по разным таблицам, выборка по ним + join

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

Поэтому если вы задаете этот вопрос, значит, вам нужно пользоваться вторым вариантом.

Тем более, при частом обновлении.

sidorka
На сайте с 17.08.2012
Offline
211
#2

Basilisk, имеет смысл денормировать все поля или только те, которые обновляются?

[Удален]
#3

вполне достаточно только те, которые обновляются

B
На сайте с 23.05.2001
Offline
195
#4
sidorka:
Basilisk, имеет смысл денормировать все поля или только те, которые обновляются?

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

Упрощенный пример - у вас есть миллиард заказов, для каждой строки заказа в таблице "Позиции заказа" есть количество и цена, при выборке вы умножаете количество на цену и получаете сумму по позиции.

Если вы заведете избыточную колонку Сумма, куда будете записывать при сохранении позиции заказа, то да - при выборке сэкономите время на вычислении, зато при обновлении, соответственно, потратите лишнее, плюс бонусом получаете дополнительный риск несоответствия данных.

Другой пример - в самой таблице "Заказы" у вас всегда будет поле "Общая сумма заказа" - чтобы сэкономить на join'ах и не подцеплять позиции заказа каждый раз, когда вам понадобится получить Номер, Дату и Сумму заказа.

sidorka
На сайте с 17.08.2012
Offline
211
#5

А по второму вопросу что скажете?

SELECT ... FROM t1 WHERE f1=value1 AND f2=value2 AND f3=value3 ORDER BY f4
SELECT ... FROM t1 JOIN t2 USING (id) JOIN t3 USING (id) WHERE t1.f1=value1 AND t2.f2=value2 AND t3.f3=value3 ORDER BY t2.f4

Если сейчас есть составной индекс f1-f2-f3-f4 в одной таблице, то при разбиении на несколько таблиц и последующих join'ах, как будут индексы работать? Время выборки не увеличится?

Сначала join присоединяет соответствующую таблицу, а потом фильтрация по условиям происходит или сначала фильтрация, а потом join?

A
На сайте с 19.07.2010
Offline
130
#6
sidorka:
Записей >100 лямов. При UPDATE и INSERT диск грузится - я так понимаю, из-за того, что индексы пересчитываются. Индексов около десяти - и простые, и составные. На чтение работает шустро.

Не видя структуру таблиц трудно давать советы...

Примари кей состоит из одного поля или составной? (С составным могут быть нюансы с дисковой нагрузкой при инсертах)

Еще можно посмотреть, нужны ли все десять индексов.

sidorka:
SELECT ... FROM t1 WHERE f1=value1 AND f2=value2 AND f3=value3 ORDER BY f4
сейчас есть составной индекс f1-f2-f3-f4

Например, тут можно погонять тесты с составным индексом на три поля: f1-f2-f3

Возможно разница по времени выполнения будет небольшая и не перекроет накладные расходы по поддержке индекса f1-f2-f3-f4 (при частых UPDATE/INSERT)

Если есть возможность, то часто изменяемые данные желательно вынести в отдельную таблицу. Т.к. при каждом UPDATE или INSERT сбрасывеатся query_cache(для конкретной таблицы) и он ставовится бесполезен.

.............
sidorka
На сайте с 17.08.2012
Offline
211
#7

Вынес обновляемые поля в отдельную таблицу. Особого эффекта не заметил. Диск все равно грузится сильно - индексы постоянно пересчитываются, как я понимаю. Обновляется часто - раз в секунду, может немного реже.

Какие еще методы есть? Только накапливать изменения и одним коммитом их забрасывать в таблицу?

siv1987
На сайте с 02.04.2009
Offline
427
#8
sidorka:
Какие еще методы есть?

Использовать кеш таблицу. И обновлять по ней обновляемые поля реже нежели раз в секунду.

sidorka:
индексы постоянно пересчитываются, как я понимаю.

Зачем вам индекс?

B
На сайте с 23.05.2001
Offline
195
#9

Выложите уже схему БД и заодно - что туда пишете, зачем вам советы "как вылечить больного без больного"?

G2
На сайте с 27.10.2009
Offline
62
#10

Еще вариант - для данных с большой динамикой и структурой, которой можно пожертвовать - использовать NoSQL, вроде redis или mongo.

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

КакМаршрутник (http://goo.gl/forms/hMgaH0s9E5) — как маршрутник, но работает.
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий