请问这个命令是否可能加快

jthkl 2018-01-26 10:31:31

ALTER procedure [dbo].[usp_QueryCommission]
@khid varchar(20),
@filter decimal(18,2),
@topcount int,
@begin datetime,
@end datetime
as
set nocount on;

;WITH cte AS (
SELECT *,ROW_NUMBER() OVER(PARTITION BY 商户号,CAST(交易时间 as date) order by 交易时间) as rn
FROM 交易流水 where 交易时间 between @begin and @end
)
SELECT 商户号,CAST(交易时间 as date) as 交易时间,count(id) as 总单号数,sum(订单金额) as 总金额
FROM cte
WHERE rn<=@topcount AND 订单金额>=@filter and 商户号=@khid
GROUP BY 商户号,CAST(交易时间 as date)



执行上面命令,每一次计算差不多要3、4秒,是因为原始数据有57万条的缘故。请问有没有办法优化语句,使得速度更快呢?我给商户号加了个索引,没啥用。
...全文
334 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
五维思考 2018-01-26
  • 打赏
  • 举报
回复
引用 5 楼 z10843087 的回复:
可能是参数嗅探的问题,,,,,
就是
OwenZeng_DBA 2018-01-26
  • 打赏
  • 举报
回复
你可以在存储过程的里面加入OPTION(RECOMPILE) 试试,

ALTER PROCEDURE [dbo].[usp_QueryCommission]
    @khid VARCHAR(20) ,
    @filter DECIMAL(18, 2) ,
    @topcount INT ,
    @begin DATETIME ,
    @end DATETIME
AS
    SET NOCOUNT  ON;

;
    WITH    cte
              AS ( SELECT   * ,
                            ROW_NUMBER() OVER ( PARTITION BY 商户号,
                                                CAST(交易时间 AS DATE) ORDER BY 交易时间 ) AS rn
                   FROM     交易流水
                   WHERE    交易时间 BETWEEN @begin AND @end
                 )
        SELECT  商户号 ,
                CAST(交易时间 AS DATE) AS 交易时间 ,
                COUNT(id) AS 总单号数 ,
                SUM(订单金额) AS 总金额
        FROM    cte
        WHERE   rn <= @topcount
                AND 订单金额 >= @filter
                AND 商户号 = @khid
        GROUP BY 商户号 ,
                CAST(交易时间 AS DATE)
    OPTION  ( RECOMPILE ); 
像这样
中国风 2018-01-26
  • 打赏
  • 举报
回复
查看执行计划,T-SQL中条件有没有走索引,查看占用资料多的步骤 比如:时间是取范围如是聚集索引效率会更好 另如果数据量大,开销会在显示结果集上,这类是没法优化的,比如你吃两碗饭一定会比吃一碗慢
OwenZeng_DBA 2018-01-26
  • 打赏
  • 举报
回复
引用 3 楼 jthkl 的回复:
[quote=引用 2 楼 z10843087 的回复:] 发下执行计划来看看吧
好神奇。如果只是执行语句

WITH cte AS (
SELECT *,ROW_NUMBER() OVER(PARTITION BY 商户号,CAST(交易时间 as date) order by 交易时间) as rn 
 FROM 交易流水    where 交易时间 between '2011-12-1' and '2017-12-31'
 )
 SELECT 商户号,CAST(交易时间 as date) as 交易时间,count(id) as 总单号数,sum(订单金额) as 总金额 
 FROM cte 
 WHERE rn<=10 AND 订单金额>=50 and 商户号='2082190'
 GROUP BY 商户号,CAST(交易时间 as date)
耗时0.83秒。 但是如果执行存储过程:

exec usp_QueryCommission
 @khid='2082190',
 @filter=10,
 @topcount=50,
 @begin='2011-12-1',
 @end='2017-12-31'
耗时4.14秒[/quote] 可能是参数嗅探的问题,,,,,
zjcxc 2018-01-26
  • 打赏
  • 举报
回复
参数化(大眼仔过程),固定值(你自己手工查的方式)和变量(存储过程的参数改成 DECLARE) 这三者的执行计划不一定是相同的 你可以再试试 DECLARE 的方法,如果效率也高,那么直接把存储过程调整的参数在存储过程里面用变量定义一次,然后查询使用变量
jthkl 2018-01-26
  • 打赏
  • 举报
回复
有点小错误。语句应该是 WHERE rn<=50 AND 订单金额>=10 and 商户号='2082190',这样才和存储过程一样。但是结果是一样的。语句比存储过程快太多了。怎么会这样?
jthkl 2018-01-26
  • 打赏
  • 举报
回复
引用 2 楼 z10843087 的回复:
发下执行计划来看看吧
好神奇。如果只是执行语句

WITH cte AS (
SELECT *,ROW_NUMBER() OVER(PARTITION BY 商户号,CAST(交易时间 as date) order by 交易时间) as rn 
 FROM 交易流水    where 交易时间 between '2011-12-1' and '2017-12-31'
 )
 SELECT 商户号,CAST(交易时间 as date) as 交易时间,count(id) as 总单号数,sum(订单金额) as 总金额 
 FROM cte 
 WHERE rn<=10 AND 订单金额>=50 and 商户号='2082190'
 GROUP BY 商户号,CAST(交易时间 as date)
耗时0.83秒。 但是如果执行存储过程:

exec usp_QueryCommission
 @khid='2082190',
 @filter=10,
 @topcount=50,
 @begin='2011-12-1',
 @end='2017-12-31'
耗时4.14秒
OwenZeng_DBA 2018-01-26
  • 打赏
  • 举报
回复
发下执行计划来看看吧
听雨停了 2018-01-26
  • 打赏
  • 举报
回复
时间应该都耗在生成rn上了吧,你单独执行一下这个看要多久。

SELECT *,ROW_NUMBER() OVER(PARTITION BY 商户号,CAST(交易时间 as date) order by 交易时间) as rn 
 FROM 交易流水    where 交易时间 between @begin and @end
OwenZeng_DBA 2018-01-26
  • 打赏
  • 举报
回复
解决了就行,,别忘记结帖
卖水果的net 2018-01-26
  • 打赏
  • 举报
回复
AND 订单金额>=@filter and 商户号=@khid
放在内层
jthkl 2018-01-26
  • 打赏
  • 举报
回复
找了文章,DBCC FREEPROCCACHE了,declare了,都不管用。甚至直接在c#用select命令,只要是参数化查询也不管用,只用拼接字符串才管用。 不过 OPTION ( RECOMPILE ); 管用了 数据库这个东西深啊,只知其然不知其所以然

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧