sql >> Database >  >> RDS >> Sqlserver

SQL Server-partitie per tabel op Tenant-ID - gebruikte schijfruimte

Hier is een goede inleiding over partitionering door Kendra Little. Het zou u moeten helpen bij het beantwoorden van de vraag of u wel of niet moet partitioneren. http://www. brentozar.com/archive/2012/03/how-decide-if-should-use-table-partitioning/

Een aanbeveling die ik heb, is ervoor te zorgen dat elke query die de tabel raakt, partitie-eliminatie in het predikaat gebruikt.

Houd er bij bestandsgroepen rekening mee dat het partitieschema de partitie toewijst aan de bestandsgroep. Dit kan ingewikkeld worden als je 1 bestandsgroep per tenant wilt doen.

Met SQL Server 2005 - 2008 R2 zijn 1.000 partities het maximum dat een tabel kan bevatten. Met 2012 hebben ze de limiet verhoogd tot 15.000 partities. Als je meer nodig hebt, plaats dan de partitiewaarden en laat het bereik bepalen naar welke partitie de gegevens zullen gaan.

Hier is een functie met tabelwaarde die u kunt gebruiken om het ruimtegebruik per partitie af te leiden:

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;

Vervolgens kunt u de functie met tabelwaarde als volgt opvragen:

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

Hierbij wordt ervan uitgegaan dat er geen pagina's uit de rij of lob zijn. Als je die hebt en ze wilt weergeven, kunnen ze eenvoudig aan de functie worden toegevoegd.




  1. WHERE en JOIN-clausules bestellen prestaties

  2. Update met join met Zend-framework

  3. Converteer SQL-query om set-operators te gebruiken

  4. Tellen op vroegste datum gevonden van een inner join?