[英]How to improve query performance
I have a lot of records in table. 我在表中有很多记录。 When I execute the following query it takes a lot of time. 当我执行以下查询时,需要花费很多时间。 How can I improve the performance? 如何提高性能?
SET ROWCOUNT 10
SELECT StxnID
,Sprovider.description as SProvider
,txnID
,Request
,Raw
,Status
,txnBal
,Stxn.CreatedBy
,Stxn.CreatedOn
,Stxn.ModifiedBy
,Stxn.ModifiedOn
,Stxn.isDeleted
FROM Stxn,Sprovider
WHERE Stxn.SproviderID = SProvider.Sproviderid
AND Stxn.SProviderid = ISNULL(@pSProviderID,Stxn.SProviderid)
AND Stxn.status = ISNULL(@pStatus,Stxn.status)
AND Stxn.CreatedOn BETWEEN ISNULL(@pStartDate,getdate()-1) and ISNULL(@pEndDate,getdate())
AND Stxn.CreatedBy = ISNULL(@pSellerId,Stxn.CreatedBy)
ORDER BY StxnID DESC
The stxn table has more than 100,000 records. stxn表有超过100,000条记录。
The query is run from a report viewer in asp.net c#. 查询是从asp.net c#中的报表查看器运行的。
This is my go-to article when I'm trying to do a search query that has several search conditions which might be optional. 当我尝试进行具有多个搜索条件的搜索查询时,这是我的首选文章。
http://www.sommarskog.se/dyn-search-2008.html http://www.sommarskog.se/dyn-search-2008.html
The biggest problem with your query is the column=ISNULL(@column, column)
syntax. 查询的最大问题是column=ISNULL(@column, column)
语法。 MSSQL won't use an index for that. MSSQL不会使用索引。 Consider changing it to (column = @column AND @column IS NOT NULL)
考虑将其更改为(column = @column AND @column IS NOT NULL)
You should consider using the execution plan and look for missing indexes. 您应该考虑使用执行计划并查找缺少的索引。 Also, how long it takes to execute? 此外,执行需要多长时间? What is slow for you? 什么对你来说很慢?
Maybe you could also not return so many rows, but that is just a guess. 也许你也不能返回那么多行,但这只是猜测。 Actually we need to see your table and indexes plus the execution plan. 实际上我们需要查看您的表和索引以及执行计划。
For one, use SELECT TOP ()
instead of SET ROWCOUNT
- the optimizer will have a much better chance that way. 首先,使用SELECT TOP ()
而不是SET ROWCOUNT
- 优化器将有更好的机会。 Another suggestion is to use a proper inner join instead of potentially ending up with a cartesian product using the old style table,table join syntax (this is not the case here but it can happen much easier with the old syntax). 另一个建议是使用正确的内连接,而不是使用旧样式表,表连接语法结束使用笛卡尔积(这不是这里的情况,但使用旧语法可以更容易)。 Should be: 应该:
...
FROM Stxn INNER JOIN Sprovider
ON Stxn.SproviderID = SProvider.Sproviderid
...
And if you think 100K rows is a lot, or that this volume is a reason for slowness, you're sorely mistaken. 如果你认为100K行很多,或者这个音量是缓慢的原因,那你就错了。 Most likely you have really poor indexing strategies in place, possibly some parameter sniffing, possibly some implicit conversions... hard to tell without understanding the data types, indexes and seeing the plan. 很可能你的索引策略确实很差,可能是一些参数嗅探,可能是一些隐式转换......如果不了解数据类型,索引和查看计划,很难说清楚。
There are a lot of things that could impact the performance of query. 有很多事情可能会影响查询的性能。 Although 100k records really isn't all that many. 虽然100k的记录真的不是那么多。
Items to consider (in no particular order) 要考虑的项目(没有特别的顺序)
Hardware: 硬件:
Database Structure: 数据库结构:
Network: 网络:
General: 一般:
Basically, it is going to be impossible to give a hard answer without a lot of questions asked by you. 基本上,如果没有你提出的很多问题,就不可能给出一个难以回答的答案。 All of these will bear out if you profile the queries, understand what and how much is going back to the client and watch the interactions amongst the various parts. 如果您分析查询,了解返回客户端的内容和数量,并观察各个部分之间的交互,所有这些都将证明。
Finally depending on the amount of data going back to the client there might not be a way to improve performance short of hardware changes. 最后,根据返回客户端的数据量,可能无法在没有硬件更改的情况下提高性能。
Make sure Stxn.SproviderID, Stxn.status, Stxn.CreatedOn, Stxn.CreatedBy, Stxn.StxnID and SProvider.Sproviderid all have indexes defined. 确保Stxn.SproviderID,Stxn.status,Stxn.CreatedOn,Stxn.CreatedBy,Stxn.StxnID和SProvider.Sproviderid都定义了索引。
(NB -- you might not need all, but it can't hurt.) (注意 - 你可能不需要所有,但它不会受到伤害。)
I don't see much that can be done on the query itself, but I can see things being done on the schema : 我没有看到可以对查询本身做多少,但我可以看到在架构上完成的事情:
Something to consider: When ROWCOUNT or TOP are used with an ORDER BY clause, the entire result set is created and sorted first and then the top 10 results are returned. 需要考虑的事项:当ROWCOUNT或TOP与ORDER BY子句一起使用时,首先创建并排序整个结果集,然后返回前10个结果。
How does this run without the Order By clause? 如果没有Order By子句,它如何运行?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.