Советы по индексам на сервере SQL - PullRequest
3 голосов
/ 12 июля 2010

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

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

Не могли бы вы предложить какой-нибудь учебник или методику оптимизации базы данных.

Пожалуйста, будьте конкретны, так как я читал много теорий, но никаких конкретных инструкций до сих пор не было

спасибо

Ответы [ 4 ]

3 голосов
/ 13 июля 2010

Некоторые избранные:

  1. Производительность тюнинга и статьи учебные пособия от SQLServerPedia
  2. Введение в индексы из SQL Сервер MVP Гейл Шоу
  3. Планы выполнения SQL Server от Гранта Фричи. Понимание планов выполнения будет быть важной частью оптимизации вашего кода. Это один из лучших SQL Server книги, которые я прочитал, и это бесплатно.
3 голосов
/ 12 июля 2010

Если он "не" сломан, не почините.Ищите медленные области вашего приложения, находите оскорбительные запросы и анализируйте эти планы запросов и решайте проблемы с индексами, если таковые имеются.Не просто начинайте вносить изменения в вашу систему, потому что вы только что узнали что-то!

дальнейшее чтение: http://blogs.msdn.com/b/bartd/archive/2007/07/19/are-you-using-sql-s-missing-index-dmvs.aspx

попробуйте этот запрос, чтобы найти отсутствующие индексы:

--based on /1200403/poisk-tablitsy-indeksa-skanirovaniya
--this query will show cahced query plans that "SCAN", change comments for other things

;WITH XMLNAMESPACES(DEFAULT N'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
, CachedPlans AS
(SELECT
     RelOp.op.value(N'../../@NodeId', N'int') AS ParentOperationID
         ,RelOp.op.value(N'@NodeId', N'int') AS OperationID
         ,RelOp.op.value(N'@PhysicalOp', N'varchar(50)') AS PhysicalOperator
         ,RelOp.op.value(N'@LogicalOp', N'varchar(50)') AS LogicalOperator
         ,RelOp.op.value(N'@EstimatedTotalSubtreeCost ', N'float') AS EstimatedCost
         ,RelOp.op.value(N'@EstimateIO', N'float') AS EstimatedIO
         ,RelOp.op.value(N'@EstimateCPU', N'float') AS EstimatedCPU
         ,RelOp.op.value(N'@EstimateRows', N'float') AS EstimatedRows
         ,cp.plan_handle AS PlanHandle
         ,qp.query_plan AS QueryPlan
         ,st.TEXT AS QueryText
         ,cp.cacheobjtype AS CacheObjectType
         ,cp.objtype AS ObjectType
         ,cp.usecounts AS UseCounts
     FROM sys.dm_exec_cached_plans                            cp
         CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle)     st
         CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle)   qp
         CROSS APPLY qp.query_plan.nodes(N'//RelOp')          RelOp (op)
)
SELECT
    PlanHandle
        ,ParentOperationID
        ,OperationID
        ,PhysicalOperator
        ,LogicalOperator
        ,UseCounts
        ,CacheObjectType
        ,ObjectType
        ,EstimatedCost
        ,EstimatedIO
        ,EstimatedCPU
        ,EstimatedRows
        ,QueryText
    FROM CachedPlans
    WHERE CacheObjectType = N'Compiled Plan'
        AND PhysicalOperator IN ('nothing will ever match this one!'
                                --,'Assert'                             
                                --,'Bitmap'
                                --,'Clustered Index Delete'
                                --,'Clustered Index Insert'
                                ,'Clustered Index Scan'
                                --,'Clustered Index Seek'
                                --,'Clustered Index Update'
                                --,'Compute Scalar'
                                --,'Concatenation'
                                --,'Constant Scan'
                                ,'Deleted Scan'
                                --,'Filter'
                                --,'Hash Match'
                                ,'Index Scan'
                                --,'Index Seek'
                                --,'Index Spool'
                                ,'Inserted Scan'
                                --,'Merge Join'
                                --,'Nested Loops'
                                --,'Parallelism'
                                ,'Parameter Table Scan'
                                --,'RID Lookup'
                                --,'Segment'
                                --,'Sequence Project'
                                --,'Sort'
                                --,'Stream Aggregate'
                                --,'Table Delete'
                                --,'Table Insert'
                                ,'Table Scan'
                                --,'Table Spool'
                                --,'Table Update'
                                --,'Table-valued function'
                                --,'Top'
                                )

или этот:

SELECT TOP 50
    total_worker_time/execution_count AS Avg_CPU_Time
        ,execution_count
        ,total_elapsed_time/execution_count as AVG_Run_Time
        ,(SELECT
              SUBSTRING(text,statement_start_offset/2,(CASE
                                                           WHEN statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(max), text)) * 2 
                                                           ELSE statement_end_offset 
                                                       END -statement_start_offset)/2
                       ) FROM sys.dm_exec_sql_text(sql_handle)
         ) AS query_text 
FROM sys.dm_exec_query_stats 
ORDER BY 3 DESC
1 голос
/ 12 июля 2010

Наиболее важные вещи, на которые стоит обратить внимание при индексации: Внешние ключи (они не индексируются автоматически и, как правило, используются в соединениях, поэтому обычно их следует индексировать, если размер таблицы не мал и будет оставаться небольшим.) Чаще всего FK нужны индексы.

Вещи в выражениях where, которые имеют достаточную изменчивость, чтобы сделать индекс полезным. Например, last_name, используемое в предложениях where, вероятно, нуждается в индексе, но поле с текстом «Y» или «N» не получит преимущества от одного. Вещи, которые вы будете заказывать часто.

Если существует только один запрос, который использует это конкретное поле в поле where или order by, не индексируйте, если запрос не занимает слишком много времени.

Вещи не для индексации: Большие поля, которые представляют собой текст или varchar (Макс) или что-то, что обычно ищется как "% text%". Они могут получить больше пользы от полнотекстового индекса, чем от обычного индекса.

Битовые поля. Нет никакого смысла индексировать битовое поле вообще (и не все базы данных могут даже разрешать индекс), поскольку у него недостаточно изменчивости, чтобы правильно использовать индекс.

Помните, что каждый индекс добавляет время для вставки, обновления или удаления. Хотя я заметил, что пользователи, как правило, допускают больше времени для выполнения этих задач, чем для возврата результатов выбора, об этом следует помнить.

1 голос
/ 12 июля 2010

Одним из самых больших и важных инструментов, используемых для анализа производительности SQL Server, является SQL Profiler. Это не совсем легко понять и использовать, поэтому этот видеофильм Master SQL Server Profiler может помочь вам понять, как использовать SQL Profiler для настройки производительности SQL Server.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...