Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Урок за разделяне на таблица на SQL Server и дялове

Проблем

В тази статия ще се съсредоточим върху демонстрацията на разделянето на таблицата. Най-простото обяснение за разделянето на таблици може да се нарече разделяне на големи таблици на малки. Тази тема предоставя мащабируемост и управляемост.

Какво е разделяне на таблици в SQL Server?

Да приемем, че имаме маса и тя расте ден след ден. В този случай таблицата може да причини някои проблеми, които трябва да бъдат решени чрез стъпките, определени по-долу:

  • Поддържайте тази таблица. Това ще отнеме много време и ще изразходва повече ресурси (CPU, IO и т.н.).
  • Резервно копие.
  • Проблеми със заключване.

Поради гореспоменатите причини имаме нужда от разделяне на таблица. Този подход има следните предимства:

  • Възможност за управление:Ако разделим таблицата, можем да управляваме всеки дял от таблицата. Например, можем да направим само един дял на таблицата.
  • Възможност за архивиране:Някои дялове на таблицата се използват само по тази причина. Не е необходимо да архивираме този дял на таблицата. Можем да използваме резервно копие на файлова група и да го архивираме само като променим дял на таблицата.
  • Ефективност на заявката:Оптимизаторът на заявки на SQL Server решава да използва елиминиране на дялове. Това означава, че SQL Server не извършва търсене на несвързания дял на таблицата.

Вертикално и хоризонтално разделяне на таблицата в SQL Server

Разделянето на таблицата е обща концепция. Има няколко типа разделяне, които работят за конкретни случаи. Най-съществените и широко използвани са двата подхода:вертикално разделяне и хоризонтално разделяне.

Специфичността на всеки тип отразява същността на таблицата като структура, състояща се от колони и редове:

• Вертикалното разделяне разделя таблицата на колони.
• Хоризонталното разделяне разделя таблицата на редове.

Най-типичният пример за разделяне на вертикална таблица е таблица на служителите с техните данни – имена, имейли, телефонни номера, адреси, рождени дни, професии, заплати и всякаква друга информация, която може да е необходима. Част от тези данни са поверителни. Освен това в повечето случаи операторите се нуждаят само от някои основни данни като имена и имейл адреси.

Вертикалното разделяне създава няколко „по-тесни“ таблици с необходимите данни. Заявките са насочени само към конкретна част. По този начин фирмите намаляват натоварването, ускоряват задачите и гарантират, че поверителни данни няма да бъдат разкрити.

Хоризонталното разделяне на таблицата води до разделяне на една обща таблица на няколко по-малки, където всяка таблица с частици има същия брой колони, но броят на редовете е по-малък. Това е стандартен подход за прекомерни таблици с хронологични данни.

Например, таблица с данните за цялата година може да бъде разделена на по-малки секции за всеки месец или седмица. Тогава заявката ще се отнася само до една конкретна по-малка таблица. Хоризонталното разделяне подобрява мащабируемостта на обемите данни с нарастването им. Разделените таблици ще останат по-малки и лесни за обработка.

Всяко разделяне на таблица в SQL сървър трябва да се разглежда внимателно. Понякога трябва да поискате данните от няколко разделени таблици наведнъж и тогава ще имате нужда от JOIN в заявките. Освен това, вертикалното разделяне все още може да доведе до големи таблици и ще трябва да ги разделите повече. В работата си трябва да разчитате на решенията за вашите специфични бизнес цели.

След като изяснихме концепцията за разделяне на таблицата в SQL Server, е време да продължим към демонстрацията.

Ще избегнем всякакви T-SQL скриптове и ще обработваме всички стъпки за разделяне на таблицата със съветника за разделяне на SQL Server.

Какво ви е необходимо, за да направите дялове на SQL база данни?

  • Примерна база данни на WideWorldImporters
  • Издание за разработчици на SQL Server 2017

Изображението по-долу ни показва как да проектираме дял на таблица. Ще направим дял на таблицата по години и ще намерим различни файлови групи.

На тази стъпка ще създадем две файлови групи (FG_2013, FG_2014). Щракнете с десния бутон върху база данни и след това щракнете върху раздела Файлови групи.

Сега ще свържем файловите групи с нови pdf файлове.

Нашата структура за съхранение на база данни е готова за разделяне на таблици. Ще намерим таблицата, която искаме да бъде разделена, и ще стартираме съветника за създаване на дял.

На екранната снимка по-долу ще изберем колона, върху която искаме да приложим функцията за дял. Избраната колона е „Дата на фактурата“.

На следващите два екрана ще назовем функция за дялове и схема на дял.

Функция за разделяне ще дефинира как да се направи дял за редовете [Продажби].[Фактури] въз основа на колоната InvoiceDate.

Схема на дялове ще дефинира карти за редовете Sales.Invoices към файлови групи.

Задайте дяловете на файлови групи и задайте границите.

Лява/дясна граница дефинира страната на всеки интервал от гранични стойности, която може да бъде лява или дясна. Ще зададем граници по този начин и ще щракнем върху Оценка на съхранение. Тази опция ни предоставя информация за броя на редовете, които трябва да бъдат разположени в границите.

И накрая, ще изберем Изпълни веднага и след това ще щракнем върху Напред.

След като операцията е успешна, щракнете върху Close.

Както можете да видите, нашата таблица Sales.Invoices е разделена. Тази заявка ще покаже подробностите за разделената таблица.

SELECT
  OBJECT_SCHEMA_NAME(pstats.object_id) AS SchemaName
  ,OBJECT_NAME(pstats.object_id) AS TableName
  ,ps.name AS PartitionSchemeName
  ,ds.name AS PartitionFilegroupName
  ,pf.name AS PartitionFunctionName
  ,CASE pf.boundary_value_on_right WHEN 0 THEN 'Range Left' ELSE 'Range Right' END AS PartitionFunctionRange
  ,CASE pf.boundary_value_on_right WHEN 0 THEN 'Upper Boundary' ELSE 'Lower Boundary' END AS PartitionBoundary
  ,prv.value AS PartitionBoundaryValue
  ,c.name AS PartitionKey
  ,CASE 
    WHEN pf.boundary_value_on_right = 0 
    THEN c.name + ' > ' + CAST(ISNULL(LAG(prv.value) OVER(PARTITION BY pstats.object_id ORDER BY pstats.object_id, pstats.partition_number), 'Infinity') AS VARCHAR(100)) + ' and ' + c.name + ' <= ' + CAST(ISNULL(prv.value, 'Infinity') AS VARCHAR(100)) 
    ELSE c.name + ' >= ' + CAST(ISNULL(prv.value, 'Infinity') AS VARCHAR(100))  + ' and ' + c.name + ' < ' + CAST(ISNULL(LEAD(prv.value) OVER(PARTITION BY pstats.object_id ORDER BY pstats.object_id, pstats.partition_number), 'Infinity') AS VARCHAR(100))
  END AS PartitionRange
  ,pstats.partition_number AS PartitionNumber
  ,pstats.row_count AS PartitionRowCount
  ,p.data_compression_desc AS DataCompression
FROM sys.dm_db_partition_stats AS pstats
INNER JOIN sys.partitions AS p ON pstats.partition_id = p.partition_id
INNER JOIN sys.destination_data_spaces AS dds ON pstats.partition_number = dds.destination_id
INNER JOIN sys.data_spaces AS ds ON dds.data_space_id = ds.data_space_id
INNER JOIN sys.partition_schemes AS ps ON dds.partition_scheme_id = ps.data_space_id
INNER JOIN sys.partition_functions AS pf ON ps.function_id = pf.function_id
INNER JOIN sys.indexes AS i ON pstats.object_id = i.object_id AND pstats.index_id = i.index_id AND dds.partition_scheme_id = i.data_space_id AND i.type <= 1 /* Heap or Clustered Index */
INNER JOIN sys.index_columns AS ic ON i.index_id = ic.index_id AND i.object_id = ic.object_id AND ic.partition_ordinal > 0
INNER JOIN sys.columns AS c ON pstats.object_id = c.object_id AND ic.column_id = c.column_id
LEFT JOIN sys.partition_range_values AS prv ON pf.function_id = prv.function_id AND pstats.partition_number = (CASE pf.boundary_value_on_right WHEN 0 THEN prv.boundary_id ELSE (prv.boundary_id+1) END)
WHERE pstats.object_id = OBJECT_ID('Sales.Invoices')
ORDER BY TableName, PartitionNumber;

MS Ефективност на разделяне на SQL сървър

Ще сравним производителността на разделена и неразделена таблица за една и съща таблица. За да направите това, използвайте заявката по-долу и активирайте Включи действителен план за изпълнение.

DECLARE @Dt as date  = '20131231'
SELECT COUNT(InvoiceDate)
  FROM [Sales].[Invoices]
  where InvoiceDate < @Dt

Когато разглеждаме плана за изпълнение, разбираме, че той включва свойства „Разделен“, „Действителен брой дялове“ и „Действителен достъпен на дялове“.

Разделено свойство показва, че тази таблица е активирана за дял.

Действителният брой дялове свойството е общият брой дялове, които се четат от двигателя на SQL Server.

Действителният достъп до разделен дял свойството е номерата на дялове, оценени от двигателя на SQL Server. SQL Server елиминира достъпа за други дялове, тъй като се нарича елиминиране на дял и печели предимство по отношение на производителността на заявката.

Сега вижте плана за изпълнение на неразделената таблица.

Основната разлика между тези два плана за изпълнение е Брой на прочетените редове тъй като това свойство показва колко реда са прочетени за тази заявка. Както можете да видите от диаграмата за компресиране по-долу, стойностите на разделената таблица са твърде ниски. Поради тази причина той ще консумира нисък IO.

След това стартирайте заявката и разгледайте плана за изпълнение.

DECLARE @DtBeg as date  = '20140502'
DECLARE @DtEnd as date  = '20140701'

SELECT COUNT(InvoiceDate)
  FROM [Sales].[Invoices]
  where InvoiceDate between @DtBeg and @DtEnd

Ескалация на заключване на ниво дял

Ескалацията на заключване е механизъм, който се използва от SQL Server Lock Manager. Той организира заключване на ниво на обекти. Когато броят на редовете, които трябва да бъдат заключени, се увеличи, мениджърът на заключване променя заключващ обект. Това е нивото на йерархия на ескалация на заключване „Ред -> Страница -> Таблица -> База данни". Но в разделената таблица можем да заключим един дял, тъй като това увеличава едновременността и производителността. Нивото по подразбиране на ескалация на заключване е „TABLE“ в SQL Server.

Изпълнете заявката с помощта на оператора UPDATE по-долу.

BEGIN TRAN
DECLARE @Dt as date  = '20131221'
UPDATE [Sales].[Invoices] SET CreditNoteReason = 'xxx'   where InvoiceDate < @Dt
SP_LOCK

Червеното поле дефинира изключително заключване, което гарантира, че множество актуализации не могат да бъдат направени на един и същ ресурс едновременно. Появява се в таблицата с фактури.

Сега ще зададем режима на ескалация за таблицата Sales.Invoices, за да я автоматизираме и да изпълним отново заявката.

ALTER TABLE Sales.Invoices SET (LOCK_ESCALATION = AUTO)

Сега червеното поле дефинира изключителното заключване на отстъпа, което защитава заявени или придобити изключителни заключвания на някои ресурси по-ниско в йерархията. Накратко това ниво на заключване ни позволява да актуализираме или изтриваме друг дял от таблици. Това означава, че можем да започнем друга актуализация или да вмъкнем друг дял на таблицата.

В предишни публикации също проучихме проблема с превключването между разделяне на таблици и предоставихме инструкциите. Тази информация може да ви бъде полезна, ако се справяте с тези случаи. Вижте статията за повече информация.

Препратки

  1. Режими на заключване
  2. Разделени таблици и индекси

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Копирайте таблици от една база данни в друга в SQL Server

  2. Заявка за блокиране на SQL Server

  3. Внедряване на обработка на грешки и транзакции в SQL Server

  4. Как да свия базата данни на SQL Server?

  5. GETUTCDATE() Примери в SQL Server (T-SQL)