sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server-partition per tabell på Tenant ID - diskutrymme används

Här är en bra primer om partitionering av Kendra Little. Det borde hjälpa dig att svara på frågan om du ska partitionera eller inte. http://www. brentozar.com/archive/2012/03/how-decide-if-should-use-table-partitioning/

En rekommendation jag har är att se till att varje fråga som träffar tabellen använder partitionseliminering i predikatet.

När det gäller filgrupper, kom ihåg att partitionsschemat mappar partitionen till filgruppen. Detta kan bli komplicerat om du vill göra en filgrupp per klient.

Med SQL Server 2005 - 2008 R2 är 1 000 partitioner det maximala som en tabell kan innehålla. Med 2012 ökade de gränsen till 15 000 partitioner. Om du behöver mer än så, placera ut partitionsvärdena och låt intervallet avgöra vilken partition som data ska gå till.

Här är en tabellvärderad funktion som du kan använda för att härleda utrymmesanvändning efter partition:

CREATE FUNCTION tvfPartitionAllocationDetails (@schema_name sysname, @table_name sysname) 
RETURNS TABLE 
AS 
RETURN

select  f.data_space_id,
        f.NAME AS file_group_name,
        SCHEMA_NAME(t.schema_id) AS table_schema,
        t.name AS table_name,
        [HOBT?] = CASE pst.index_id WHEN 0 THEN 'HEAP' WHEN 1 THEN 'B-TREE' END,
        p.partition_number,
        ps.name AS partition_scheme_name,
        pf.name AS partition_function_name,
        partition_function_range = CASE pf.boundary_value_on_right WHEN 1 THEN 'RIGHT' WHEN 0 THEN 'LEFT' END,
        left_prv.value AS left_range,
        right_prv.value AS right_value,
        ISNULL(STR(CAST(left_prv.value AS BIGINT)), '-INF')
        + CASE WHEN pf.boundary_value_on_right = 0 THEN ' < '
               ELSE ' <= '
          END + 'X' + CASE WHEN pf.boundary_value_on_right = 0 THEN ' <= '
                           ELSE ' < '
                      END + ISNULL(STR(CAST(right_prv.value AS BIGINT)), 'INF') AS range_desc
        ,SUM(used_page_count) * 8 [TableSpaceUsed(KB)]
        ,(SELECT SUM(ISNULL(used_page_count,0)) * 8 FROM sys.dm_db_partition_stats  WHERE object_id = p.OBJECT_ID AND partition_number = p.partition_number AND index_id > 1) [NCIndexSpaceUsed(KB)]
        ,SUM(used_page_count) used_page_count
        ,row_count
from sys.dm_db_partition_stats pst
INNER JOIN sys.partitions p ON pst.partition_id = p.partition_id
JOIN    sys.tables t
        ON p.object_id = t.object_id
JOIN    sys.indexes i
        ON p.object_id = i.object_id
        AND p.index_id = i.index_id
JOIN    sys.allocation_units au
        ON p.hobt_id = au.container_id
JOIN    sys.filegroups f
        ON au.data_space_id = f.data_space_id
LEFT JOIN    sys.partition_schemes ps
        ON ps.data_space_id = i.data_space_id
LEFT JOIN    sys.partition_functions pf
        ON ps.function_id = pf.function_id
LEFT JOIN sys.partition_range_values left_prv
        ON left_prv.function_id = ps.function_id
           AND left_prv.boundary_id + 1 = p.partition_number
LEFT JOIN sys.partition_range_values right_prv
        ON right_prv.function_id = ps.function_id
           AND right_prv.boundary_id = p.partition_number
where pst.object_id = object_id(quotename(@schema_name) + '.' + quotename(@table_name)) 
    AND used_page_count > 0 
    AND pst.index_id IN (0,1)/*Remove Nonclustered index counts*/

GROUP BY f.data_space_id,
        f.NAME,
        t.schema_id,
        t.name,
        p.partition_number,
        ps.name,
        pf.name,
        pf.boundary_value_on_right,
        left_prv.value,
        right_prv.value,
        ISNULL(STR(CAST(left_prv.value AS BIGINT)), '-INF')
        + CASE WHEN pf.boundary_value_on_right = 0 THEN ' < '
               ELSE ' <= '
          END + 'X' + CASE WHEN pf.boundary_value_on_right = 0 THEN ' <= '
                           ELSE ' < '
                      END + ISNULL(STR(CAST(right_prv.value AS BIGINT)), 'INF') ,
        row_count,
        p.OBJECT_ID,
        pst.index_id;

Sedan kan du fråga den tabellvärderade funktionen så här:

SELECT * FROM dbo.tvfPartitionAllocationDetails('dbo','mytablename');

Detta förutsätter inga sidor utanför rad eller lob. Om du har sådana och vill visa dem kan de enkelt läggas till i funktionen.




  1. Android Room - Hur man återställer automatisk genererad tabell primärnyckel vid varje appkörning

  2. Fel vid försök att hämta text för fel ORA-01804

  3. Hur får man fram nyckelfälten för en tabell i plpgsql-funktionen?

  4. Phalcon prestandarelaterade frågor