Когда индекс не стоит обновлять

Существует ли приемлемое соотношение операций чтения и записи, которое делает индекс полезным, или оно меньше, чем это?

Я использую это:

WITH    UnusedIndexQuery ( Object_ID, ObjectName, IndexName, Index_ID, Reads, Writes, Rows )
          AS ( SELECT
                s.object_id ,
                objectname = OBJECT_NAME(s.OBJECT_ID) ,
                indexname = i.name ,
                i.index_id ,
                reads = user_seeks + user_scans + user_lookups ,
                writes = user_updates ,
                p.rows
               FROM
                sys.dm_db_index_usage_stats s
               JOIN 
                sys.indexes i
               ON
                i.index_id = s.index_id
                AND s.OBJECT_ID = i.OBJECT_ID
               JOIN 
                sys.partitions p
               ON
                p.index_id = s.index_id
                AND s.OBJECT_ID = p.OBJECT_ID
               WHERE
                OBJECTPROPERTY(s.OBJECT_ID, 'IsUserTable') = 1
                AND s.database_id = DB_ID()
                AND i.type_desc = 'nonclustered'
                AND i.is_primary_key = 0
                AND i.is_unique_constraint = 0
                AND p.rows > 10000
             ),
        IndexSizes ( schemaname, tablename, object_id, indexname, index_id, indextype, indexsizekb, indexsizemb, indexsizegb )
          AS ( SELECT
                sys_schemas.name AS SchemaName ,
                sys_objects.name AS TableName ,
                sys_objects.[object_id] AS object_id ,
                sys_indexes.name AS IndexName ,
                sys_indexes.index_id AS index_id ,
                sys_indexes.type_desc AS IndexType ,
                partition_stats.used_page_count * 8 AS IndexSizeKB ,
                CAST(partition_stats.used_page_count * 8 / 1024.00 AS DECIMAL(10,
                                                              3)) AS IndexSizeMB ,
                CAST(partition_stats.used_page_count * 8 / 1048576.00 AS DECIMAL(10,
                                                              3)) AS IndexSizeGB
               FROM
                sys.dm_db_partition_stats partition_stats
               INNER JOIN sys.indexes sys_indexes
               ON
                partition_stats.[object_id] = sys_indexes.[object_id]
                AND partition_stats.index_id = sys_indexes.index_id
                AND sys_indexes.type_desc <> 'HEAP'
               INNER JOIN sys.objects sys_objects
               ON
                sys_objects.[object_id] = partition_stats.[object_id]
               INNER JOIN sys.schemas sys_schemas
               ON
                sys_objects.[schema_id] = sys_schemas.[schema_id]
                AND sys_schemas.name <> 'SYS'
             )
    SELECT
        [IndexSizes].[tablename] ,
        [IndexSizes].[indexname] ,
        [IndexSizes].[indextype] ,
        [IndexSizes].[indexsizekb] ,
        [IndexSizes].[indexsizemb] ,
        [IndexSizes].[indexsizegb] ,
        UnusedIndexQuery.Reads ,
        UnusedIndexQuery.Writes ,
        CAST(CASE WHEN [Reads] = 0 THEN 1
                  ELSE [Reads]
             END / CASE WHEN [Writes] = 0 THEN 1
                        ELSE writes
                   END AS NVARCHAR(8)) + ':1' AS [Benefit Ratio (Read:Write)] ,
        UnusedIndexQuery.[Rows]
    FROM
        UnusedIndexQuery
    INNER JOIN IndexSizes
    ON  UnusedIndexQuery.object_id = IndexSizes.object_id
        AND UnusedIndexQuery.index_id = IndexSizes.index_id
    ORDER BY
        CASE WHEN [Reads] = 0 THEN 1
             ELSE [Reads]
        END / CASE WHEN [Writes] = 0 THEN 1
                   ELSE writes
              END ,
        reads ,
        [Writes] DESC ,
        [indexsizemb] DESC

чтобы получить представление о состоянии преимуществ моих индексов.

С двух сторон результатов я ясен - 1 000 000 операций чтения и 0 операций записи = хороший индекс для ускорения поиска данных, 1 000 000 операций записи и 0 операций чтения означает, что мы поддерживаем индекс для нулевой ссылки.
В чем я не уверен, так это где активность показана как более сбалансированная - где я могу сделать индексы сокращения и начала отбрасывания?

Спасибо

Джонатан

2 ответа

Решение

Я не думаю, что имеет смысл основывать решение только на количестве операций чтения / записи (если, конечно, вы не читаете ==0, но тогда почему у вас есть таблица?:-)).

Считают, что:

  • даже если чтения мало, они могут быть очень трудоемкими без индекса
  • чтения могут быть более критичными по времени, чем записи, поэтому индекс может стоить того, несмотря на снижение производительности записи
  • производительность записи не обязательно страдает; Я бы предположил, что большинство современных СУБД могут задерживать обновление индекса до тех пор, пока оно не потребуется, поэтому, например, много последовательных вставок должны вызывать только одно обновление индекса

Короче говоря, как всегда, единственный совет: профиль перед оптимизацией. Там нет простого ярлыка:-/.

Чего ты пытаешься достичь? Вы пытаетесь улучшить производительность ввода-вывода? у вас мало места на диске? Преждевременная оптимизация - корень всего зла!

Придерживайтесь быстрых побед, таких как 0 читает и 100 000 000 записей. Все остальное - компромисс. Если на вашем сервере есть запас, но нет места на диске, то начните работать в обратном направлении с самого низкого отношения чтения к записи и следите за производительностью.

Может быть разумнее изучить другие альтернативы, такие как оптимизация процедур / запросов, добавление сжатия страниц, добавление дискового пространства /RAM и т. Д.

Другие вопросы по тегам