2009-09-22 3 views
2

У одного из моих Клиентов есть система на основе бронирования. Подобно воздушным линиям. Работает на MS SQL 2005.Лучший способ разработать таблицу на основе бронирования

Способ, которым предыдущая компания разработала это, - это создать распределение в виде набора строк.

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

AllocationId | SeatNumber | IsSold 

1234   | A01  | 0 

1234   | A02  | 0 

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

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

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

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

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

+0

Используются ли все записи или вы можете архивировать некоторые старые данные? –

+0

Есть ли у вас какие-либо статистические данные о том, как долго выполняется одно заявление об обновлении?SQL Server довольно хорош с генерацией статистики - я не могу себе представить, что это слишком сложно получить. –

ответ

0

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

Некоторые от экспромтом Hardward идеи:

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

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

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

+0

Мы используем RAID 50 на данный момент, имеем возможность перейти на RAID 10 при следующем обновлении, спасибо за подсказку. У меня есть стадо твердотельных дисков, которые начинают улучшать производительность, но мне не нравится, когда я использую «новейшую» технологию, так как это немного похоже на бета-тестирование на моих глазах :). – Joe

+0

SSD действительно звучат (a) очень круто и (б) очень дорого. (У меня есть эта ментальная картина набора массивных USB-накопителей, выпущенных из серверной стойки ...) Вероятность того, что они работают очень хорошо, но цена и доступные размеры могут быть непомерно высокими. –

0

Как длина является блокировкой обновления для?

Почему замок на «стол» не только «строки» продаются?

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

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

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

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

+0

Снова извините, плохая формулировка, они просто блокировки на уровне строк и страниц. Все это в одном сохраненном проце, так что к концу одного proc его разблокировали. Когда ничто не использует систему, это занимает долю секунды, но когда у нас есть 1-2000 пользователей, мы получаем от 30 секунд до минуты, чтобы запустить proc, и как только это выходит за минуту, мы начинаем получать тайм-ауты и мертвый замок. Также у нас есть много других запросов, использующих те же таблицы, в то время как это происходит, поэтому мы рассматриваем любые другие факторы, которые могут повлиять на него, но я знаю, что никто из явно заблокировал таблицу, поэтому я предполагаю, что она будет ОК. – Joe

0

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

Select allow_row_locks, allow_page_locks from sys.indexes where name = 'IndexNameHere' 
+0

Извините, плохая формулировка, а не блокировки таблиц, они просто блокировки строк и страниц и включены для всех индексов, которые они используют в инструкции обновления – Joe

0

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

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

После того как система начинает замедляя из-за слишком большого количества замков нет смысла начинать больше сделок.

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

Oracle является хорошо позволяя reads to bypass writes, однако SqlServer не так standared ...

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

  • be SNAPSHOT (или READ UNCOMMITTED) сделка
  • найти «ИД» рядов для мест, которые вы хотите продать.
  • Затем вы должны совершить (или отменить) эту сделку,

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

  • Большинство likcly читается COMMITTED, (или, возможно, SERIALIZABLE)
  • Выбор каждой строки для обновления (использовать locking hint)
  • Проверить это не было продано в среднем время (прервать и начать снова, если у него есть)
  • Установите флажок «IsSold» на строке

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

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

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

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

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

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

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

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

В случае, если это помогает, я подробно расскажу об этом предмете в своей книге (включая SSD, оптимизацию дискового массива и т. Д.) - Ultra-Fast ASP.NET.