Хоча ця публікація не буде повною відповіддю через відсутність інформації, вона повинна мати можливість направити вас у правильному напрямку чи іншим чином зрозуміти, яким ви згодом зможете поділитися з громадою.
На жаль, це визначення призводить до погіршення продуктивності щодо попередньої ситуації з таблицею на основі диска. Порядок величини більш-менш на 10% вище (що в деяких випадках досягає 100%, тому вдвічі більше часу).
Найбільше я очікував отримати перевагу в сценаріях з високою конкурентоспроможністю, враховуючи безблокову архітектуру, яку рекламує Microsoft. Натомість найгірші показники - це саме те, коли на столі є декілька одночасних користувачів, які виконують кілька запитів.
Це викликає занепокоєння, оскільки це точно не повинно бути. Певні робочі навантаження не передбачені в таблицях пам'яті (SQL 2014), і деякі робочі навантаження піддаються цьому. У більшості ситуацій може бути мінімальний приріст продуктивності лише шляхом міграції та вибору належних індексів.
Спочатку я дуже вузько думав над вашими питаннями щодо цього:
Запитання:
- який правильний BUCKET_COUNT встановити?
- який індекс я повинен використовувати?
- чому продуктивність гірша, ніж у таблиці на основі диска?
Спочатку я вважав, що в таблиці пам’яті є проблема, коли фактичні в таблиці пам'яті не є оптимальними. Хоча є певні проблеми з визначенням хеш-індексу, оптимізованим для пам'яті, я вважаю, що справжня проблема полягає у використанні запитів.
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
Ця вставка повинна бути надзвичайно швидкою, якщо вона стосується лише таблиці пам'яті. Однак, він також включає таблицю, засновану на диску, і підлягає всьому блокуванню та блокуванню, пов'язаному з цим. Таким чином, відходи реального часу тут знаходяться на таблиці на основі диска.
Коли я зробив швидкий тест на вкладку 100000 рядків з таблиці на основі диска після завантаження даних у пам'ять - це було час другого відгуку. Однак більшість ваших даних зберігаються лише протягом дуже короткого часу, менше 20 секунд. Це не дає йому багато часу, щоб реально жити в кеші. Окрім того, я не впевнений, наскільки AnotherTable
насправді великий , і не знаю, чи відчиняються цінні з диска чи ні. Ми повинні розраховувати на вас за ці відповіді.
За допомогою запиту Вибір:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1
Знову ж таки, ми перебуваємо на милі ефективність таблиці на основі interop + диска. Крім того, сортування не є дешевим для індексів HASH, і слід використовувати некластеризований індекс. Про це йдеться у посібнику з індексів, який я пов'язав у коментарях.
Щоб навести фактичні факти, засновані на дослідженнях, я завантажив SearchItems
таблицю пам'яті з 10 мільйонами рядків і AnotherTable
зі 100 000, оскільки не знав фактичного розміру чи статистики. Потім я використовував вищезазначений запит для виконання. Крім того, я створив розширений сеанс подій на wait_completed і помістив його в кільце. Її прибирали після кожного пробігу. Я також побіг DBCC DROPCLEANBUFFERS
імітувати обстановку, де всі дані можуть не мати пам'яті.
Якщо дивитися на них у вакуумі, результати були не надзвичайні. Оскільки ноутбук, на якому я тестую це, використовує SSD вищого класу, я штучно знизив продуктивність на основі диска для VM, який я використовую.
Результати надійшли без інформації про очікування після 5 запусків запиту лише в таблиці на основі пам'яті (видалення об'єднання та відсутність підзапитів). Це майже як і очікувалося.
Однак, використовуючи оригінальний запит, у мене були очікування. У цьому випадку сенс, коли дані зчитуються з диска, має сенс PAGEIOLATCH_SH. Оскільки я є єдиним користувачем у цій системі і не витрачав час на створення масивного тестового середовища для вставок, оновлень, видалень із об'єднаної таблиці, я не очікував, що будь-яке блокування чи блокування набуде чинності.
У цьому випадку ще раз значна частина часу була витрачена на таблицю на основі диска.
Нарешті, запит на видалення. Пошук рядків на основі просто ID1 не є надзвичайно ефективним, якщо має індекс. Хоча це правда, що предикати рівності - це те, для чого хеш-індекси належать, відро, в яке потрапляють дані, базується на всіх хешованих стовпцях. Таким чином, id1, id2, де id1 = 1, id2 = 2, і id1 = 1, id2 = 3 буде хеш в різні відра, оскільки хеш буде поперек (1,2) і (1,3). Це не буде простим скануванням діапазону B-Tree, оскільки хеш-індекси не структуровані однаково. Тоді я б очікував, що це не буде ідеальним показником для цієї операції, однак я б не очікував, що він прийме замовлення на величину довше, ніж досвід. Мені було б цікаво подивитися на цю інформацію на wait_info.
Найбільше я очікував отримати перевагу в сценаріях з високою конкурентоспроможністю, враховуючи безблокову архітектуру, яку рекламує Microsoft. Натомість найгірші показники - це саме те, коли на столі є декілька одночасних користувачів, які виконують кілька запитів.
Хоча це правда, що замки використовуються для логічної послідовності, операції все одно повинні бути атомними. Це робиться за допомогою спеціального оператора порівняння на основі процесора (саме тому In-Memory працює лише з певними [хоча й майже усіма процесорами, зробленими за останні 4 роки] процесорами). Таким чином, ми не отримуємо все безкоштовно, ще буде якийсь час для завершення цих операцій.
Ще один момент, який підсумовує, полягає в тому, що майже у всіх запитах використовуваний інтерфейс - це T-SQL (а не власне складені SPROC), які стосуються хоча б однієї дискової таблиці. Ось чому я вважаю, врешті-решт, насправді ми не маємо підвищеної продуктивності, оскільки ми все ще обмежені роботою таблиць на диску.
Слідувати:
Створіть розширений сеанс події для wait_completed та вкажіть відомий вам SPID. Запустіть запит і дайте нам висновок або споживайте його внутрішньо.
Повідомте нам про вихід з №1.
Немає магічного числа для визначення кількості відра для хеш-індексів. В основному до тих пір, поки відра не будуть повністю заповнені і ланцюги рядків залишаються нижче 3 або 4, продуктивність повинна залишатися прийнятною. Це на зразок запитання: "На що мені слід встановити файл журналу?" - це залежатиме від процесу, від бази даних, від типу використання.
OPTION(OPTIMIZE FOR UNKNOWN)
(див. Підказки таблиці )?