2015-02-10 290 views
0

這基本上是同樣的問題在問(Solution for speeding up a slow SELECT DISTINCT query in Postgres解決方案加快慢速SELECT DISTINCT查詢的SQL Server

這是很相同的情況下,龐大的部署數據庫,這是不可能正常化它因舊的舊應用程序。新的行不斷添加,舊的行被刪除符合某些標準。 我以CTE試過的建議,我在這裏看到沒有性能增益, 漂亮相同的執行時間爲原來的

select distinct [somecolumn] 
from bigtable 

同樣適用於建議使用Group by

似乎最好的工作是建議創建視圖並查詢視圖。 (緩存已在查詢之間復位)

我需要一些建議,因爲我不明白爲什麼會導致更好的性能。

create view [dbo].[vwDistinct] 
with schemabinding 
as 
    select 
     [somecolumn], count_big(*) as TableCount 
    from 
     dbo.BigTable 
    where 
     somecolumn IS NOT NULL 
    group by 
     somecolumn; 

select distinct somecolumn 
from vwDistinct 

應用程序使用存儲過程進行調用。該數據庫的SQL Server 2008 R2,但如果有很好的理由,它可以移動到SQL Server 2014

謝謝

這是vwDistinct

<?xml version="1.0" encoding="utf-16"?> 
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.2" Build="12.0.2000.8" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"> 
    <BatchSequence> 
    <Batch> 
     <Statements> 
     <StmtSimple StatementCompId="1" StatementEstRows="41138.3" StatementId="1" StatementOptmLevel="FULL" CardinalityEstimationModelVersion="70" StatementSubTreeCost="5.10782" StatementText="select somecolumn from vwDistinct" StatementType="SELECT" QueryHash="0x23700E4CF62A8E4E" QueryPlanHash="0x79D8240601D270CB" RetrievedFromCache="true"> 
      <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" /> 
      <QueryPlan NonParallelPlanReason="EstimatedDOPIsOne" CachedPlanSize="16" CompileTime="59" CompileCPU="18" CompileMemory="336"> 
      <MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" /> 
      <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="1239807" EstimatedPagesCached="77487" EstimatedAvailableDegreeOfParallelism="1" /> 
      <RelOp AvgRowSize="37" EstimateCPU="1.03877" EstimateIO="4.06905" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="944197" LogicalOp="Clustered Index Scan" NodeId="1" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="5.10782" TableCardinality="944197"> 
       <OutputList> 
       <ColumnReference Database="[BigData]" Schema="[dbo]" Table="[vwDistinct]" Column="somecolumn" /> 
       </OutputList> 
       <IndexScan Ordered="false" ForcedIndex="false" ForceScan="false" NoExpandHint="true" Storage="RowStore"> 
       <DefinedValues> 
        <DefinedValue> 
        <ColumnReference Database="[BigData]" Schema="[dbo]" Table="[vwDistinct]" Column="somecolumn" /> 
        </DefinedValue> 
       </DefinedValues> 
       <Object Database="[BigData]" Schema="[dbo]" Table="[vwDistinct]" Index="[cdxDistinct]" IndexKind="ViewClustered" Storage="RowStore" /> 
       <IndexedViewInfo> 
        <Object Database="[BigData]" Schema="[dbo]" Table="[BigTable]" /> 
       </IndexedViewInfo> 
       </IndexScan> 
      </RelOp> 
      </QueryPlan> 
     </StmtSimple> 
     </Statements> 
    </Batch> 
    </BatchSequence> 
</ShowPlanXML> 
爲 選擇somecolumn執行計劃
+1

由於視圖按某個列進行分組,所以它只會返回不同的一些列。所以你可以只做「從vwDistinct中選擇一些列」,然後得到不同的值! – jarlh 2015-02-10 10:04:21

+0

您可以在該列上添加索引 – 2015-02-10 10:05:25

+1

表中有多少行以及'somecolumn'中有多少個不同的值? – 2015-02-10 10:07:00

回答

3
<Object Database="[BigData]" Schema="[dbo]" Table="[vwDistinct]" Index="[cdxDistinct]" IndexKind="ViewClustered" Storage="RowStore" /> 

顯示您的視圖已編入索引。根據你的評論你的狀態

大約2.5-3千萬行,大約有100個不同的值。

查詢

select distinct [somecolumn] 
from bigtable 

不認爲會掃描表中的索引2.5+百萬行找到的所有不同的值。

然而,該視圖將僅包含100行。所以當它存在時,它可以對視圖的聚集索引執行掃描以找到所有不同的值。

成本是所有插入和修改somecolumn的更新將會更加昂貴。