SSMS
 sql >> Cơ Sở Dữ Liệu >  >> Database Tools >> SSMS

Có bất kỳ cách nào để thực hiện theo chương trình một truy vấn với Bao gồm Kế hoạch thực thi thực tế và xem liệu có bất kỳ đề xuất chỉ mục nào hay không

Đầu tiên, trước khi tôi đi vào cách lấy Kế hoạch thực thi thực tế trong mã và tìm những kế hoạch báo cáo cần lập chỉ mục, tôi khuyên bạn nên xem xét bằng cách sử dụng Database Engine Tuning Adviser (DTA) , bạn có thể cung cấp cho nó một danh sách tất cả các truy vấn và nó sẽ xử lý chúng cho bạn biết các chỉ mục, thống kê có thể có và nhiều thứ khác có thể giúp lập kế hoạch cho các truy vấn của bạn.

Thậm chí, tốt hơn so với việc cung cấp cho nó một danh sách hơn 1 triệu truy vấn là bạn có thể nhận được dấu vết từ máy chủ với các truy vấn thực tế đang được chạy và nó sẽ tập trung vào các truy vấn chiếm nhiều thời gian nhất.

Để trả lời câu hỏi ban đầu của bạn, bạn sẽ cần thêm SET STATISTICS XML ON khi bắt đầu kết nối, điều này sẽ cung cấp cho bạn dữ liệu XML mà GUI mà bạn đã hiển thị dựa trên. ( Xem tại đây để biết thêm thông tin về việc nhận kế hoạch ). Khi bạn làm điều đó, các truy vấn của bạn sẽ trả về với một tập hợp kết quả bổ sung chứa xml cho kế hoạch ở hàng đầu tiên của cột đầu tiên.

Đây là một chức năng nhanh và dễ thực hiện điều đó.

private static string GetXmlPlanForQuery(string queryText)
{
    string result = null;
    using (var connection = new SqlConnection(connectionString))
    using (var command = new SqlCommand())
    {
        connection.Open();
        command.Connection = connection;

        //Enable the statistics.
        command.CommandText = "SET STATISTICS XML ON";
        command.ExecuteNonQuery();

        //Run through the query, keeping the first row first column of the last result set.
        command.CommandText = queryText;
        using (var reader = command.ExecuteReader())
        {
            object lastValue = null;
            do
            {
                if (reader.Read())
                {
                    lastValue = reader.GetValue(0);
                }
            } while (reader.NextResult());

            if (lastValue != null)
            {
                result = lastValue as string;
            }
        }
    }
    return result;
}

Và đây là XML nó được trả về cho truy vấn select TOTAL_SALES from clients where ACTIVE = 0; mà tôi đã chạy mà tôi có trên một trong các cơ sở dữ liệu cục bộ của mình.

<?xml version="1.0"?>
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="11.0.5058.0">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementText="SELECT [TOTAL_SALES] FROM [clients] WHERE [ACTIVE][email protected]" StatementId="1" StatementCompId="1" StatementType="SELECT" RetrievedFromCache="false" StatementSubTreeCost="0.0767454" StatementEstRows="315" StatementOptmLevel="FULL" QueryHash="0x708AE72DD31A316" QueryPlanHash="0x214EA79FF76E6771" StatementOptmEarlyAbortReason="GoodEnoughPlanFound">
          <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"/>
          <QueryPlan DegreeOfParallelism="1" CachedPlanSize="16" CompileTime="1" CompileCPU="1" CompileMemory="192">
            <MissingIndexes>
              <MissingIndexGroup Impact="94.0522">
                <MissingIndex Database="[exampleDb]" Schema="[dbo]" Table="[CLIENTS]">
                  <ColumnGroup Usage="EQUALITY">
                    <Column Name="[ACTIVE]" ColumnId="15"/>
                  </ColumnGroup>
                  <ColumnGroup Usage="INCLUDE">
                    <Column Name="[TOTAL_SALES]" ColumnId="18"/>
                  </ColumnGroup>
                </MissingIndex>
              </MissingIndexGroup>
            </MissingIndexes>
            <MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0"/>
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="830838" EstimatedPagesCached="207709" EstimatedAvailableDegreeOfParallelism="2"/>
            <RelOp NodeId="0" PhysicalOp="Clustered Index Scan" LogicalOp="Clustered Index Scan" EstimateRows="315" EstimateIO="0.0749769" EstimateCPU="0.0017685" AvgRowSize="16" EstimatedTotalSubtreeCost="0.0767454" TableCardinality="1465" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
              <OutputList>
                <ColumnReference Database="[exampleDb]" Schema="[dbo]" Table="[CLIENTS]" Column="TOTAL_SALES"/>
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="315" ActualEndOfScans="1" ActualExecutions="1"/>
              </RunTimeInformation>
              <IndexScan Ordered="0" ForcedIndex="0" ForceScan="0" NoExpandHint="0">
                <DefinedValues>
                  <DefinedValue>
                    <ColumnReference Database="[exampleDb]" Schema="[dbo]" Table="[CLIENTS]" Column="TOTAL_SALES"/>
                  </DefinedValue>
                </DefinedValues>
                <Object Database="[exampleDb]" Schema="[dbo]" Table="[CLIENTS]" Index="[imp_clpk_CLIENTS]" IndexKind="Clustered"/>
                <Predicate>
                  <ScalarOperator ScalarString="[exampleDb].[dbo].[CLIENTS].[ACTIVE]=(0)">
                    <Compare CompareOp="EQ">
                      <ScalarOperator>
                        <Identifier>
                          <ColumnReference Database="[exampleDb]" Schema="[dbo]" Table="[CLIENTS]" Column="ACTIVE"/>
                        </Identifier>
                      </ScalarOperator>
                      <ScalarOperator>
                        <Const ConstValue="(0)"/>
                      </ScalarOperator>
                    </Compare>
                  </ScalarOperator>
                </Predicate>
              </IndexScan>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@1" ParameterCompiledValue="(0)" ParameterRuntimeValue="(0)"/>
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>

Bây giờ, vì Microsoft khá tốt, nếu bạn điều hướng đến không gian tên được liệt kê trong XML bạn thực sự có thể nhận được một bản sao của .xsd cho định dạng. Sau đó, bạn có thể thực hiện xsd showplanxml.xsd /classes từ dấu nhắc lệnh của nhà phát triển. và nó sẽ cung cấp cho bạn một showplanxml.cs mà bạn có thể sử dụng với XmlSerializer .

Đây là một chương trình ví dụ nhỏ giúp trình gỡ lỗi phá vỡ một chỉ mục bị thiếu.

static void Main(string[] args)
{
    string result = GetXmlPlanForQuery("select TOTAL_SALES from clients where ACTIVE = 0;");
    XmlSerializer ser = new XmlSerializer(typeof(ShowPlanXML));
    var plan = (ShowPlanXML)ser.Deserialize(new StringReader(result));

    var missingIndexes =
        plan.BatchSequence.SelectMany(x => x)
            .SelectMany(x => x.Items)
            .OfType<StmtSimpleType>()
            .Select(x => x.QueryPlan)
            .Where(x => x.MissingIndexes != null && x.MissingIndexes.Any());

    foreach (var queryPlan in missingIndexes)
    {
        //This will hit for each statement in the query that was missing a index, check queryPlan.MissingIndexes to see the indexes that are missing.
        Debugger.Break();
    }

    Console.WriteLine("Done");
    Console.ReadLine();
}

Tôi đã sử dụng XmlSerializer và giải nén nó thành một lớp nhưng bạn có thể dễ dàng tải nó vào một XDocument, sau đó sử dụng XPath để tìm tất cả các nút có tên MissingIndex .




  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. Làm cách nào để tìm các lần lặp lại {min, max} với các mẫu biểu thức chính quy trong Visual Studio hoặc SSMS Tìm và Thay thế?

  2. Không thể kết nối với Plesk v12 SQL Server từ xa từ SQL Server Management Studio

  3. SQL Server Management Studio - tìm thủ tục được lưu trữ theo tên trên nhiều cơ sở dữ liệu

  4. SQL Server sao chép tất cả các hàng từ một bảng sang một bảng khác, tức là bảng trùng lặp

  5. Làm thế nào để truy xuất dữ liệu từ SQL Server dựa trên ví dụ dưới đây?