我的情况:我的申请很慢。它变得很慢......主要是因为我感觉我的dataTables / grid的服务器分页被错误地实现了。
让我们开始吧:
我有一个SQL Server 2008数据库,一个包含所有信息的表,其中有10列,目前是19K行
我的应用程序基于JavaScript和ASP.Net后端代码。
我的SQL查询是:
WITH Ordered AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY Created DESC) AS 'RowNumber'
FROM Meetings
WHERE State IN ('Appointed', 'Accepted')
AND [xxx] LIKE '%1%'
AND [yyy] LIKE '%2%'
)
SELECT *
FROM Ordered
WHERE RowNumber BETWEEN 1 AND 41;
所以目前此查询运行大约27到32秒,这意味着超过30秒我得到超时...在1年内19k行...这意味着在1个月内最新的每个查询将对死。 ..
据我所知,此查询的顺序是问题:此处没有完成索引。 因为查询首先排序,然后用手动行号选择所有,然后只选择40 ...(当然在我的网格的第2页上它得到第41行到第81行......)
我 COULD 在我的“Created desc”上做一个索引,查询会快得多, BUT 每列都可以对我的网格进行排序,这意味着“创建了desc” “可能是我桌上的每个其他列,当然还有desc和asc order!
那么,如何改进呢?
//编辑:
很抱歉忘记:
内部查询(内部选择)运行6秒,而总查询运行31秒...... 这意味着“WITH ORDERES AS”就是问题所在!
答案 0 :(得分:2)
首先要做的事情是:您遇到了性能问题,采用适当的方法并采取适当的措施。 内部查询(内部选择)运行6秒,而总查询运行31秒......这意味着...... 是业余主义。请阅读How to analyse SQL Server performance以了解衡量效果的正确方法。在我们继续之前,如果你从6秒开始,你已经输掉了比赛。
现在,回答这个问题。
WHERE State in('Appointed','Accepted') AND [xxx] LIKE '%1%' AND [yyy] LIKE '%2%'
此表达式基本上是不可索引的。即使你在State
上添加一个索引,它也无济于事,因为它的基数较低(每个行的行数很少)。并且like '% ... %'
是无法索引的,因为它会在文本中间搜索值。
您可以尝试将like '% ... %'
替换为CONTAINS ...
这样的全文搜索,这将更快,您可以搜索特定的足够条款。但它确实需要您正确部署和配置full-text indexes。
至于分页,我不太赞同ROWNUMBER
方法。即使存在排序列,它也会涉及扫描和计数以跳过行数,并在您转到更高页面时变得越来越慢。我更推荐基于密钥的方法:
SELECT TOP (page size) ...
WHERE keys > <last row>
ORDER BY...
但这种方法更难实现,因为它需要跟踪键而不是页码。
但期待没有奇迹。您要求关系OLTP系统执行ElasticSearch / Solr的工作。它永远不会像你期望的那样工作。使用适合作业的工具(搜索引擎)。另请阅读Dynamic Search Conditions in T‑SQL进行更全面的讨论,但同样,不要期待奇迹。