【问题标题】:a table contains more than 10 lacs records一个表包含超过 10 条 lacs 记录
【发布时间】:2011-04-19 05:11:09
【问题描述】:

在我们项目的数据库中,我们只有一张表,其中有 10 多条 lac 记录。

这个特殊的表使我们的网络应用程序的性能太慢了。

【问题讨论】:

  • 你确定是表导致了性能问题吗?可能是查询或缺少索引。
  • 这不是一张足够大的表,如果它被正确索引并且查询设计得当,它不会注意到任何性能影响。

标签: database sql-server-2005


【解决方案1】:

你能补充更多细节吗?到目前为止,您分享的信息不足以给您很好的回应。可能有很多事情会导致性能问题。在寻找解决方案之前,您需要先缩小范围并清楚地隔离问题。

  1. 选择@@VERSION 以获取完整版本
  2. 这个盒子有多少内存?
  3. 通过以下查询分享详细信息

    SELECT 
        object_name(s.object_id) AS 'Table Name'
        , i.name AS 'Index Name'
        , i.index_id
        , user_updates AS 'Total Writes'
        , user_seeks
        , user_scans 
        , user_lookups
    FROM sys.dm_db_index_usage_stats AS s WITH (NOLOCK)
    INNER JOIN sys.indexes AS i WITH (NOLOCK)
    ON s.object_id = i.object_id
    AND i.index_id = s.index_id
    WHERE objectproperty(s.object_id,'IsUserTable') = 1
    AND s.database_id = db_id()
    AND i.object_id = object_id('YourTableName')
  1. 分享以下缺失索引 DMV 的详细信息,看看您是否有任何涉及上述表格的查询。

    
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    WITH XMLNAMESPACES
    (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') SELECT TOP 25--ecp.plan_handle, DENSE_RANK() OVER ( ORDER BY ecp.plan_handle ) AS ArbitraryPlanNumber , n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') * ISNULL(n.value('(./QueryPlan/MissingIndexes/MissingIndexGroup/@Impact)[1]','float'), 0) * ecp.usecounts AS Improvement , query_plan AS CompleteQueryPlan , n.value('(@StatementId)[1]', 'float') AS StatementID , n.value('(@StatementText)[1]', 'VARCHAR(4000)') AS StatementText , n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') AS StatementSubTreeCost , n.query('./QueryPlan/MissingIndexes') MissingIndex , n.value('(./QueryPlan/MissingIndexes/MissingIndexGroup/@Impact)[1]','float') IndexImpact , ecp.usecounts FROM sys.dm_exec_cached_plans AS ecp CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS eqp CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS qn ( n ) WHERE n.value('(./QueryPlan/MissingIndexes/MissingIndexGroup/@Impact)[1]','float') IS NOT NULL AND --ecp.usecounts > 100 AND eqp.query_plan.exist('declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; /ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple/QueryPlan/MissingIndexes') = 1 ORDER BY Improvement DESC
  2. 您是否检查过高 CPU 使用率、逻辑读取、高执行次数的查询统计信息?

    
    -- Cached SP's By Execution Count
    SELECT TOP (100) OBJECT_NAME(qt.objectid) AS 'SP Name', qs.execution_count AS 'Execution Count',
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second', qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime', qs.total_worker_time AS 'TotalWorkerTime', qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime', qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads, DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache' FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt WHERE qt.dbid = db_id() -- Filter by current database ORDER BY qs.execution_count DESC;

    -- Cached SP's By Worker Time SELECT TOP (50) OBJECT_NAME(qt.objectid) AS 'SP Name', qs.total_worker_time AS 'TotalWorkerTime', qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime', qs.execution_count AS 'Execution Count', ISNULL(qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()), 0) AS 'Calls/Second', ISNULL(qs.total_elapsed_time/qs.execution_count, 0) AS 'AvgElapsedTime', qs.max_logical_reads, qs.max_logical_writes, DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache in Minutes' FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt WHERE qt.dbid = db_id() -- Filter by current database ORDER BY qs.total_worker_time DESC;

    -- Cached SP's By Logical Reads SELECT TOP (50) OBJECT_NAME(qt.objectid) AS 'SP Name', total_logical_reads, qs.execution_count AS 'Execution Count', total_logical_reads/qs.execution_count AS 'AvgLogicalReads', qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second', qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime', qs.total_worker_time AS 'TotalWorkerTime', qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime', qs.total_logical_writes, qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads, DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache' FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt WHERE qt.dbid = db_id() -- Filter by current database ORDER BY total_logical_reads DESC;

  3. 您查看过等待统计信息吗?

    
    WITH Waits AS
    (SELECT wait_type, wait_time_ms / 1000. AS wait_time_s,
        100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
        ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn
     FROM sys.dm_os_wait_stats
     WHERE wait_type NOT IN( 'BROKER_TASK_STOP', 
      'SQLTRACE_BUFFER_FLUSH', 'CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT', 'BROKER_TRANSMITTER',
      'LAZYWRITER_SLEEP', 'SQLTRACE_WAIT_ENTRIES')) -- filter out additional irrelevant waits
    SELECT W1.wait_type, 
      CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
      CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
      CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
    FROM Waits AS W1
    INNER JOIN Waits AS W2
    ON W2.rn <= W1.rn
    GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
    HAVING SUM(W2.pct) - W1.pct < 99; -- percentage threshold
  4. 您是否看到系统中有阻塞?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-02
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    相关资源
    最近更新 更多