Альтернативний спосіб стиснення NVARCHAR (MAX)?


14

Я намагаюся стиснути деякі таблиці, у яких є NVARCHAR(MAX)поля. На жаль, rowі pageстиснення не мають бажання (лише ~ 100/200 МБ збережено для таблиці 20 ГБ). Також я не в змозі застосувати архівні стискання стовпців і зберігання стовпців, оскільки вони не підтримують стиснення NVARCHAR(MAX)полів.

Хтось може сказати, чи є у мене альтернативи тут?

Я також припускаю , що rowі pageстиск не має ефекту , оскільки зміст NVARCHAR(MAX)стовпців є унікальним.


2
Чи напевно значення стовпців ширші за 8000 символів? наприклад, SELECT MAX (CAST (LEN (широкий стовпчик) AS AS BIGINT)) З Dbo.largeTable Інакше ви можете перетворити їх у звичайний varchar і застосувати кластерні стовпці.
wBob

@wBob Навіть якщо найбільше значення склало лише 2000 символів, чи не перетворило б це на VARCHARпотенційну причину втрати даних, якщо використовуються символи з більш ніж 1 кодової сторінки? Я думаю, що пораду слід перетворити, NVARCHAR(4000)якщо максимальна довжина не перевищує 4000, оскільки тоді всі значення будуть придатні до повного стиснення Unicode. Тим не менше, напевно, можна з урахуванням інформації в запитанні вважати, що значення знаходяться набагато більше 4000 символів, тому вони наразі не стискаються.
Соломон Руцький

Відповіді:


16

Стиснення сторінок і рядків не стискає BLOB .

Через їх розмір типи даних великого значення іноді зберігаються окремо від звичайних даних про рядки на сторінках спеціального призначення. Стиснення даних недоступне для даних, що зберігаються окремо.

Якщо ви хочете стиснути BLOB, вам потрібно зберегти їх як VARBINARY(MAX)і застосувати алгоритм стиснення потоку за вибором. Наприклад GZipStream. Існує багато прикладів, як це зробити, просто шукайте GZipStream і SQLCLR.


10

Існує (зараз) потенційно два способи досягти спеціального стиснення:

  1. Починаючи з SQL Server 2016, є вбудовані функції для COMPRESS та DECOMPRESS . Ці функції використовують алгоритм GZip.

  2. Використовуйте SQLCLR для реалізації будь-якого алгоритму, який ви обрали (як @Remus згадується у його відповіді). Цей параметр доступний у версіях до SQL Server 2016, починаючи від SQL Server 2005.

    GZip - це простий вибір, оскільки він доступний у .NET та підтримуваних бібліотеках .NET Framework (код може бути в SAFEАсамблеї). Або якщо ви хочете GZip, але не хочете мати справу з кодуванням / розгортанням, ви можете використовувати функції Util_GZip та Util_GUnzip , які доступні у безкоштовній версії бібліотеки SQL # SQLCLR (автор якої я є).

    Якщо ви вирішили використовувати GZip, чи кодуєте ви його самостійно, чи використовуєте SQL #, майте на увазі, що алгоритм, який використовується в .NET для стиснення GZip, змінився в Framework версії 4.5 на краще (див. Розділ «Зауваження» на MSDN сторінка для класу GZipStream ). Це означає:

    1. Якщо ви використовуєте SQL Server 2005, 2008 або 2008 R2 - всі вони пов'язані з CLR v 2.0, який обробляє Framework версії 2.0, 3.0 та 3.5 - то зміна, внесена в Framework версії 4.5, не впливає, і ви, на жаль, затрималися Оригінальний, вдалий алгоритм .NET.
    2. Якщо ви використовуєте SQL Server 2012 або новішу версію (поки що 2014 та 2016 рр.) - всі вони пов'язані з CLR v 4.0, який обробляє версії Framework 4.0, 4.5.x, 4.6 - тоді ви можете використовувати новіший, кращий алгоритм. Єдина вимога - ви оновили .NET Framework на сервері, на якому працює SQL Server, на версію 4.5 або новішу.

    Однак вам не доведеться використовувати GZip і вільні впроваджувати будь-який алгоритм на зразок.

ВВАГА: ПРИМІТКА: всі вищезазначені методи є скоріше "робочими", а не фактичними замінами, хоча технічно це "альтернативні способи стиснення даних NVARCHAR (MAX)". Різниця полягає в тому, що за допомогою вбудованого стиснення даних - rowі page- пропонованого SQL Server, стиснення обробляється поза кадром, і дані все ще є корисними, читабельними та індексуються. Але стиснення будь-яких даних VARBINARYозначає, що ви економите місце, але відмовитеся від певної функціональності. Правда, рядок 20k не можна індексувати, але вона все одно може бути використана вWHEREпунктом або з будь-якими рядковими функціями. Для того, щоб робити що-небудь зі спеціальним стислим значенням, вам потрібно буде розпакувати його на льоту. При стисненні двійкових файлів (PDF, JPEG тощо) це не проблема, але це питання було специфічним для NVARCHARданих.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.