我有一個包含定義調試信息表如下:與ROWNUMBER選擇需要長時間來執行
id INT NOT NULL IDENTITY
message TEXT NOT NULL
date DATETIME NOT NULL
反對,我運行以下查詢:
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) AS RowNum, *
FROM debug WHERE message LIKE @Filter
) AS tbl
WHERE RowNum > (@Page*200-200)
AND RowNum <= (@Page * 200)
ORDER BY ID DESC
這給了我一個單頁200個結果;但在表中有220k個條目(並計數!),過濾和行編號需要相當長的時間(> 30秒)。
有什麼我可以做的,以加快獲得結果頁的過程?
編輯:所以我已經切換到VARCHAR(MAX)戈登建議;但這並沒有加快速度。查詢產生的執行計劃如下(我嘗試重新繪製圖形的ASCII藝術):
Sequence Project Clustered Index Scan
SELECT <- Sort <- Filter <- Top <- (Compute Scalar) <- Segment <- Filter <- [debug].[PK_debug]
Cost: 0% 26% 0% 0% 0% 0% 2% 71%
或XML:
<?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.2569.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId="4" StatementEstRows="16.4317" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="120" StatementSubTreeCost="0.0438369" StatementText="SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) AS RowNum, * FROM debug WHERE message LIKE @Filter) AS tbl WHERE RowNum > (@Page*200-200) AND RowNum <= (@Page * 200) ORDER BY ID DESC" StatementType="SELECT" QueryHash="0x535D30B424597DBB" QueryPlanHash="0x17ABB516DFF1A1A7" 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 DegreeOfParallelism="0" NonParallelPlanReason="EstimatedDOPIsOne" MemoryGrant="1024" CachedPlanSize="32" CompileTime="4" CompileCPU="4" CompileMemory="248">
<MemoryGrantInfo SerialRequiredMemory="512" SerialDesiredMemory="672" RequiredMemory="512" DesiredMemory="672" RequestedMemory="1024" GrantWaitTime="0" GrantedMemory="1024" MaxUsedMemory="56" />
<OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="256000" EstimatedPagesCached="16000" EstimatedAvailableDegreeOfParallelism="1" />
<RelOp AvgRowSize="4055" EstimateCPU="0.000207573" EstimateIO="0.0112613" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="16.4317" LogicalOp="Sort" NodeId="0" Parallel="false" PhysicalOp="Sort" EstimatedTotalSubtreeCost="0.0438369">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
<ColumnReference Column="Expr1002" />
</OutputList>
<MemoryFractions Input="1" Output="1" />
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRebinds="1" ActualRewinds="0" ActualRows="147" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<Sort Distinct="false">
<OrderBy>
<OrderByColumn Ascending="false">
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
</OrderByColumn>
</OrderBy>
<RelOp AvgRowSize="4055" EstimateCPU="8.8E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="16.4317" LogicalOp="Filter" NodeId="1" Parallel="false" PhysicalOp="Filter" EstimatedTotalSubtreeCost="0.0323681">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
<ColumnReference Column="Expr1002" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="147" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<Filter StartupExpression="false">
<RelOp AvgRowSize="4055" EstimateCPU="1E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="100" LogicalOp="Top" NodeId="2" Parallel="false" PhysicalOp="Top" EstimatedTotalSubtreeCost="0.0322801">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
<ColumnReference Column="Expr1002" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="147" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<Top RowCount="false" IsPercent="false" WithTies="false">
<TopExpression>
<ScalarOperator ScalarString="CASE WHEN CONVERT_IMPLICIT(bigint,[@Page]*(200),0) IS NULL OR CONVERT_IMPLICIT(bigint,[@Page]*(200),0)<(0) THEN (0) ELSE CONVERT_IMPLICIT(bigint,[@Page]*(200),0) END">
<IF>
<Condition>
<ScalarOperator>
<Logical Operation="OR">
<ScalarOperator>
<Compare CompareOp="IS">
<ScalarOperator>
<Identifier>
<ColumnReference Column="ConstExpr1007">
<ScalarOperator>
<Convert DataType="bigint" Style="0" Implicit="true">
<ScalarOperator>
<Arithmetic Operation="MULT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@Page" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(200)" />
</ScalarOperator>
</Arithmetic>
</ScalarOperator>
</Convert>
</ScalarOperator>
</ColumnReference>
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="NULL" />
</ScalarOperator>
</Compare>
</ScalarOperator>
<ScalarOperator>
<Compare CompareOp="LT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="ConstExpr1007">
<ScalarOperator>
<Convert DataType="bigint" Style="0" Implicit="true">
<ScalarOperator>
<Arithmetic Operation="MULT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@Page" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(200)" />
</ScalarOperator>
</Arithmetic>
</ScalarOperator>
</Convert>
</ScalarOperator>
</ColumnReference>
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(0)" />
</ScalarOperator>
</Compare>
</ScalarOperator>
</Logical>
</ScalarOperator>
</Condition>
<Then>
<ScalarOperator>
<Const ConstValue="(0)" />
</ScalarOperator>
</Then>
<Else>
<ScalarOperator>
<Identifier>
<ColumnReference Column="ConstExpr1007">
<ScalarOperator>
<Convert DataType="bigint" Style="0" Implicit="true">
<ScalarOperator>
<Arithmetic Operation="MULT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@Page" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(200)" />
</ScalarOperator>
</Arithmetic>
</ScalarOperator>
</Convert>
</ScalarOperator>
</ColumnReference>
</Identifier>
</ScalarOperator>
</Else>
</IF>
</ScalarOperator>
</TopExpression>
<RelOp AvgRowSize="4055" EstimateCPU="0.00284444" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="100" LogicalOp="Compute Scalar" NodeId="3" Parallel="false" PhysicalOp="Sequence Project" EstimatedTotalSubtreeCost="0.0322701">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
<ColumnReference Column="Expr1002" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="147" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<SequenceProject>
<DefinedValues>
<DefinedValue>
<ColumnReference Column="Expr1002" />
<ScalarOperator ScalarString="row_number">
<Sequence FunctionName="row_number" />
</ScalarOperator>
</DefinedValue>
</DefinedValues>
<RelOp AvgRowSize="4055" EstimateCPU="0.00071111" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="100" LogicalOp="Segment" NodeId="4" Parallel="false" PhysicalOp="Segment" EstimatedTotalSubtreeCost="0.0322621">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
<ColumnReference Column="Segment1008" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="147" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<Segment>
<GroupBy />
<SegmentColumn>
<ColumnReference Column="Segment1008" />
</SegmentColumn>
<RelOp AvgRowSize="4047" EstimateCPU="0.347654" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="100" LogicalOp="Filter" NodeId="5" Parallel="false" PhysicalOp="Filter" EstimatedTotalSubtreeCost="0.0322601">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="147" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<Filter StartupExpression="false">
<RelOp AvgRowSize="4047" EstimateCPU="0.434724" EstimateIO="9.53275" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1111.11" LogicalOp="Clustered Index Scan" NodeId="6" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.0312823" TableCardinality="395061">
<OutputList>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="395061" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<IndexScan Ordered="true" ScanDirection="BACKWARD" ForcedIndex="false" ForceSeek="false" ForceScan="false" NoExpandHint="false" Storage="RowStore">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="id" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="date" />
</DefinedValue>
</DefinedValues>
<Object Database="[timeflex]" Schema="[dbo]" Table="[debug]" Index="[PK_debug]" IndexKind="Clustered" Storage="RowStore" />
</IndexScan>
</RelOp>
<Predicate>
<ScalarOperator ScalarString="[timeflex].[dbo].[debug].[message] like [@Filter]">
<Intrinsic FunctionName="like">
<ScalarOperator>
<Identifier>
<ColumnReference Database="[timeflex]" Schema="[dbo]" Table="[debug]" Column="message" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Column="@Filter" />
</Identifier>
</ScalarOperator>
</Intrinsic>
</ScalarOperator>
</Predicate>
</Filter>
</RelOp>
</Segment>
</RelOp>
</SequenceProject>
</RelOp>
</Top>
</RelOp>
<Predicate>
<ScalarOperator ScalarString="[Expr1002]>CONVERT_IMPLICIT(bigint,[@Page]*(200)-(200),0) AND [Expr1002]<=CONVERT_IMPLICIT(bigint,[@Page]*(200),0)">
<Logical Operation="AND">
<ScalarOperator>
<Compare CompareOp="GT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="Expr1002" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Column="ConstExpr1006">
<ScalarOperator>
<Convert DataType="bigint" Style="0" Implicit="true">
<ScalarOperator>
<Arithmetic Operation="SUB">
<ScalarOperator>
<Arithmetic Operation="MULT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@Page" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(200)" />
</ScalarOperator>
</Arithmetic>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(200)" />
</ScalarOperator>
</Arithmetic>
</ScalarOperator>
</Convert>
</ScalarOperator>
</ColumnReference>
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
<ScalarOperator>
<Compare CompareOp="LE">
<ScalarOperator>
<Identifier>
<ColumnReference Column="Expr1002" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Column="ConstExpr1007">
<ScalarOperator>
<Convert DataType="bigint" Style="0" Implicit="true">
<ScalarOperator>
<Arithmetic Operation="MULT">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@Page" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(200)" />
</ScalarOperator>
</Arithmetic>
</ScalarOperator>
</Convert>
</ScalarOperator>
</ColumnReference>
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
</Logical>
</ScalarOperator>
</Predicate>
</Filter>
</RelOp>
</Sort>
</RelOp>
<ParameterList>
<ColumnReference Column="@Page" ParameterRuntimeValue="(1)" />
<ColumnReference Column="@Filter" ParameterRuntimeValue="'%ZUser888%'" />
</ParameterList>
</QueryPlan>
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>
你怎麼知道問題是'row_number()'而不是'like'?此外,在更新版本的SQL Server中,您可以使用'OFFSET' /'FETCH'進行分頁。 –
這將掃描所有220K條目。 ROW_NUMBER不是瓶頸,然而,在我看來,30多秒是用於查詢的時間。 –
@GordonLinoff在我的情況下,它是Microsoft SQL Server 2014(RTM-CU14)(KB3158271) - 12.0.2569.0(X64)2016年5月27日15:06:08 Copyright(c)Microsoft Corporation Standard Edition(64-bit)on Windows NT 6.3(Build 9600:)(Hypervisor)',但它至少要在2010年,2012年,2014年和2016年工作。另外,我寫了「過濾和行編號」,其中「過濾」就是LIKE。 –
Alexander