Лучший способ создать таблицу на основе бронирования - PullRequest
2 голосов
/ 22 сентября 2009

У одного из моих клиентов есть система бронирования. Похоже на воздушные линии. Работает на MS SQL 2005.

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

Простой пример:

AllocationId | SeatNumber | IsSold

1234         | A01        | 0

1234         | A02        | 0

В процессе продажи сиденья система установит блокировку обновления на столе.

В данный момент у нас есть проблема, когда процесс блокировки идет медленно, и мы ищем способы ускорить его.

Таблица уже эффективно проиндексирована, поэтому мы ищем аппаратное решение для ускорения процесса. Таблица содержит около 5 миллионов активных строк и находится в массиве RAID 50 SAS.

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

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

Ответы [ 5 ]

0 голосов
/ 15 ноября 2009

Вот несколько идей:

  1. Убедитесь, что ваши данные и журналы находятся на отдельных шпинделях, чтобы максимизировать производительность записи.
  2. Сконфигурируйте свои диски, чтобы использовать только первые 30% или около того для данных, а оставшиеся должны быть для резервных копий (минимизируйте время поиска / произвольного доступа).
  3. Использовать RAID 10 для тома журнала; добавьте больше шпинделей по мере необходимости (производительность записи зависит от скорости журнала)
  4. Убедитесь, что на вашем сервере достаточно оперативной памяти. В идеале, все необходимое для транзакции должно быть в памяти перед началом транзакции, чтобы минимизировать время блокировки (рассмотрите возможность предварительного кэширования). Для этого есть несколько счетчиков производительности.
  5. Разделение может помочь, но это во многом зависит от деталей вашего приложения и данных ...

Я предполагаю, что T-SQL, индексы, размер транзакции и т. Д. Уже оптимизированы.

Если это поможет, я подробно расскажу об этом в своей книге (включая твердотельные накопители, оптимизацию дискового массива и т. Д.) - Сверхбыстрый ASP.NET .

0 голосов
/ 12 октября 2009

Последняя попытка ...

Очевидно, что слишком много блокировок удерживается слишком долго.

Как только система начинает замедляться из-за слишком большого количества замков нет Точка в запуске больше транзакций.

Поэтому вы должны сравнить систему, чтобы узнать оптимальное количество транзакций смородины , а затем использовать некоторую систему очередей (или иным образом) для ограничения количества транзакций смородины. Sql Server может иметь некоторые настройки (количество активных соединений и т. Д.), Чтобы помочь, в противном случае вам придется написать это в коде приложения.

Oracle хорош в разрешении чтения для обхода записи , однако SqlServer не так стандартизирован ...

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

  • быть SNAPSHOT (или ЧИТАТЬ НЕОГРАНИЧЕННУЮ) транзакцию
  • найдите «Id» строк для мест, которые вы хотите продать.
  • Затем вы должны зафиксировать (или прервать) эту транзакцию,

и использовать 2-ю (надеюсь очень короткую) транзакцию, которая

  • Наиболее вероятно ЧИТАЕТСЯ, (или, может быть, Сериализуемо)
  • Выбирает каждую строку для обновления (используйте подсказку блокировки )
  • Проверьте, что он не был продан в это время (прервите и начните снова, если он есть)
  • Установить флаг «IsSold» в строке

(Вы можете выполнить вышеизложенное в одном операторе обновления, используя «in», а затем проверить, что ожидаемое количество строк было обновлено)

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

Если таблица меньше, то обновление короче и замки удерживайте меньшее время.

Поэтому рассмотрим разбиение таблицы:

  • поэтому у вас есть таблица, в которой ПРОСТО содержатся «AllocationId» и «IsSold».
  • Эта таблица может храниться как одно btree (индексированная организованная таблица по AllocationId)
  • Поскольку все остальные индексы будут находиться в таблице, которая противоречит сведениям о месте, обновление не должно блокировать индексы.
0 голосов
/ 22 сентября 2009

Как long блокировка обновления удерживать для ?

Почему блокировка на « таблице » не только на « строках » продается?

Если блокировка удерживается более доля секунды, которая может быть твоей проблемой. SqlServer не как вы держите замки в то время как пользователи заполните веб-формы и т. д.

С помощью SqlServer вы должны самостоятельно реализовать «корзину покупок», временно зарезервировав место, пока пользователь не заплатит за него. Например, добавьте столбцы «IsReserved» и «ReservedAt», тогда любые места, которые были зарезервированы для более чем n минут, должны быть автоматически зарезервированы.

Это сложная проблема, так как покупатель не ожидает, что имеющееся в наличии место будет продано кому-то еще, где он проверяет. Однако вы не знаете, завершит ли покупатель проверку. Так как вы показываете это на пользовательском интерфейсе. Подумайте о том, что делают другие сайты бронирования, а затем скопируйте тот, который ваши пользователи уже знают, как им пользоваться.

(Oracle иногда может справиться с сохранением блокировки в течение длительного времени, но даже Oracle будет на намного быстрее и счастливее , если вы продолжите блокировку коротко.)

0 голосов
/ 26 сентября 2009

Сначала я бы попытался выяснить, почему вы блокируете таблицу, а не просто строку. Одна вещь, которую нужно проверить - это план выполнения оператора Update, чтобы увидеть, какие индексы он вызывает для обновления, а затем убедиться, что row_level_lock и page_level_lock включены в этих индексах. Вы можете сделать это с помощью следующего утверждения.

Select allow_row_locks, allow_page_locks from sys.indexes where name = 'IndexNameHere'
0 голосов
/ 22 сентября 2009

Я не думаю, что вы получите что-то от разбиения таблиц - единственное улучшение, которое вы получили бы, это уменьшение количества операций чтения с диска из меньших (более коротких) деревьев индексов (каждое чтение будет достигать каждого уровня индекса по крайней мере, один раз, поэтому, чем меньше уровней, тем быстрее будет чтение.) Однако у меня есть таблица с разделом строк 4M +, проиндексированным на 4 столбца, с чистой длиной 10 байт. Он вписывается в три уровня индекса, при этом самый верхний уровень заполнен на 42,6%. Предполагая, что у вас было что-то похожее, кажется разумным, что разбиение может удалить только один уровень из дерева, и я сомневаюсь, что это большая часть улучшения.

Некоторые странные идеи:

Рейд 5 (и 50) может быть медленнее при записи из-за вычисления четности. Не проблема (или мне так сказали), если кеш дискового ввода-вывода достаточно велик для обработки рабочей нагрузки, но если он заполнен, вы можете посмотреть на raid 10.

Разделите таблицу по нескольким дисковым массивам. Возьмите два (или более) RAID-массива, распределите таблицу по томам [файлы / группы файлов, с разделением таблицы или с разделенными представлениями или без нее], и вы получите удвоенную скорость ввода-вывода на диск, в зависимости от того, где находятся данные относительно запросов, извлекающих его. (Если все в массиве № 1 и массиве № 2 простаивает, вы ничего не получили.)

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

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