我的数据仓库中有一个简单的查询(如下),为其创建了正确的索引。查询计划总是说估计的行数大约是 1 或 2,而它应该是大约 6,000,000。我运行 sp_updatestats 'resample' 并检查了统计直方图,它显示 EQ_ROWS 为 6,000,000,其中 DWDateEnd = 12/31/9999,所以我很难过。所有表中 99% 的行的 DWDateEnd 为 12/31/9999。如果我删除 DWDateEnd 过滤器,估计的行数会变得相当准确。它似乎通过在应该进行哈希连接的地方引起嵌套循环来减慢我的查询速度。帮助!
SELECT r.OrderID
FROM DWOrders r
JOIN DWOrderStatus rs ON r.OrderID = rs.OrderID AND rs.StatusID = 5 AND rs.ExpiredDate IS NULL
WHERE rs.StatusTimeStamp BETWEEN @StartDate AND @EndDate AND r.DWDateEnd = '12/31/9999'
AND rs.DWDateEnd = '12/31/9999'
这是执行计划。
<?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.1" Build="10.50.4000.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId="3" StatementEstRows="2.48996" StatementId="3" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.00817222" StatementText="
SELECT r.OrderID
 FROM DWOrder r
 JOIN DWOrderStatus rs ON r.OrderID = rs.OrderID AND rs.StatusID = 5 AND rs.ExpiredDate IS NULL AND rs.DWDateEnd = '12/31/9999' 
 WHERE rs.StatusTimeStamp BETWEEN @StartDate AND @EndDate AND r.DWDateEnd = '12/31/9999' 

" StatementType="SELECT" QueryHash="0x24DFCAFA0E610FB3" QueryPlanHash="0x6DD5D50E203E6273">
<StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
<QueryPlan CachedPlanSize="24" CompileTime="6" CompileCPU="6" CompileMemory="472">
<RelOp AvgRowSize="11" EstimateCPU="1.0408E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="2.48996" LogicalOp="Inner Join" NodeId="0" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.00817222">
<OutputList>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrder]" Alias="[r]" Column="OrderID" />
</OutputList>
<NestedLoops Optimized="false">
<OuterReferences>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="OrderID" />
</OuterReferences>
<RelOp AvgRowSize="11" EstimateCPU="0.000159131" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1.93725" LogicalOp="Index Seek" NodeId="1" Parallel="false" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.00328413" TableCardinality="24961700">
<OutputList>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="OrderID" />
</OutputList>
<IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" ForceScan="false" NoExpandHint="false">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="OrderID" />
</DefinedValue>
</DefinedValues>
<Object Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Index="[IX_DWOrderStatus_DWDateEnd_ExpiredDate_SID_STS_RID]" Alias="[rs]" IndexKind="NonClustered" />
<SeekPredicates>
<SeekPredicateNew>
<SeekKeys>
<Prefix ScanType="EQ">
<RangeColumns>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="DWDateEnd" />
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="ExpiredDate" />
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="StatusID" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="'9999-12-31 00:00:00.000'">
<Const ConstValue="'9999-12-31 00:00:00.000'" />
</ScalarOperator>
<ScalarOperator ScalarString="NULL">
<Const ConstValue="NULL" />
</ScalarOperator>
<ScalarOperator ScalarString="(5)">
<Const ConstValue="(5)" />
</ScalarOperator>
</RangeExpressions>
</Prefix>
<StartRange ScanType="GE">
<RangeColumns>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="StatusTimeStamp" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="[@StartDate]">
<Identifier>
<ColumnReference Column="@StartDate" />
</Identifier>
</ScalarOperator>
</RangeExpressions>
</StartRange>
<EndRange ScanType="LE">
<RangeColumns>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="StatusTimeStamp" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="[@EndDate]">
<Identifier>
<ColumnReference Column="@EndDate" />
</Identifier>
</ScalarOperator>
</RangeExpressions>
</EndRange>
</SeekKeys>
</SeekPredicateNew>
</SeekPredicates>
</IndexScan>
</RelOp>
<RelOp AvgRowSize="11" EstimateCPU="0.000158414" EstimateIO="0.003125" EstimateRebinds="0.937251" EstimateRewinds="0" EstimateRows="1.28531" LogicalOp="Index Seek" NodeId="2" Parallel="false" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.00487768" TableCardinality="8048090">
<OutputList>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrder]" Alias="[r]" Column="OrderID" />
</OutputList>
<IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" ForceScan="false" NoExpandHint="false">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrder]" Alias="[r]" Column="OrderID" />
</DefinedValue>
</DefinedValues>
<Object Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrder]" Index="[IX_DWOrder_DWDateEnd]" Alias="[r]" IndexKind="NonClustered" />
<SeekPredicates>
<SeekPredicateNew>
<SeekKeys>
<Prefix ScanType="EQ">
<RangeColumns>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrder]" Alias="[r]" Column="DWDateEnd" />
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrder]" Alias="[r]" Column="OrderID" />
</RangeColumns>
<RangeExpressions>
<ScalarOperator ScalarString="'9999-12-31 00:00:00.000'">
<Const ConstValue="'9999-12-31 00:00:00.000'" />
</ScalarOperator>
<ScalarOperator ScalarString="[EcommArchive].[dbo].[DWOrderStatus].[OrderID] as [rs].[OrderID]">
<Identifier>
<ColumnReference Database="[EcommArchive]" Schema="[dbo]" Table="[DWOrderStatus]" Alias="[rs]" Column="OrderID" />
</Identifier>
</ScalarOperator>
</RangeExpressions>
</Prefix>
</SeekKeys>
</SeekPredicateNew>
</SeekPredicates>
</IndexScan>
</RelOp>
</NestedLoops>
</RelOp>
</QueryPlan>
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>
一件有趣的事情是,如果我将 = '12/31/9999' 更改为 >= '12/31/9999' 然后它使用哈希连接,但希望我更改大部分索引。