SQL'ORDER BY'缓慢

Kap*_*psh 11 database sql-server-2005

ORDER BY通常很慢吗?我试图运行一些sql语句,其中该WHERE子句非常简单,但后来我尝试ORDER BYVARCHAR(50)索引列上.

出于显示原因,我需要按字母顺序排序.我认为让数据库为我做这个是最有效的.

在这一点上,我期待着

  • 优化sql查询
  • 在代码中对结果集进行排序

这是我尝试运行的实际查询:

// B.SYNTAX is a TEXT/CLOB field
// Indexes on NAME, MODULENAME. PREVIOUS is a CHAR(1) with no index
"SELECT A.NAME, B.SYNTAX, B.DESCRIPTION, A.RATE1, A.RATE2, 
A.RATE3, A.STARTDATE, A.ENDDATE, A.HIDE, A.CATEGORYNAME 
FROM A, B WHERE A.MODULENAME='"+loadedModuleName+"' 
AND A.NAME = B.NAME AND (A.PREVIOUS<>'N' OR A.PREVIOUS IS NULL) 
ORDER BY A.NAME"
Run Code Online (Sandbox Code Playgroud)

表A的大小约为2000行,B约为500行.

我可能还应该提到,由于我们支持多个数据库,因此无法进行太多数据库特定的优化.此外,该应用程序部署在客户站点.

我期待返回数百条记录(少于1000条).

你会怎么做?任何提示都表示赞赏.谢谢.

Mar*_*ham 8

索引字段上的排序应该很慢,因为它可以按索引顺序提取数据.您可能希望提供有关数据库结构(DDL)和实际查询的信息,以便人们可以查看.

你应该尽可能使用SQL排序而不是代码排序,这样你就可以在那里找到正确的轨道.

更新: 好的,一些事情.首先,您不应该使用"+ loadedModuleName +"构造,因为它使每个查询都是唯一的并且搞砸了优化器.使用参数.其次,你的Order by子句是关于表A还是B的含糊不清 - 明确表示并选择带有索引的表(即使两者都有索引,也要明确).最后,您的"上一个"字段仍然可以作为char(1)进行索引.我会做所有事情,但最后建议的索引,测试速度,如果仍然很慢,去索引并再次检查.

更新所以你将返回<1000条记录,但总共有多少桌面大小?

更新哦,伙计,对不起,我之前没有抓到这个.如果要在SQL Server上正确部署它,您的查询应该是:

SELECT A.NAME, B.SYNTAX, B.DESCRIPTION, A.RATE1, A.RATE2, A.RATE3, A.STARTDATE, A.ENDDATE, A.HIDE, A.CATEGORYNAME 
FROM Table1 A join Table2 B on (A.Name=B.Name)
WHERE (A.MODULENAME=@ModuleName) AND (A.PREVIOUS<>'N' OR A.PREVIOUS IS NULL) 
ORDER BY A.NAME
Run Code Online (Sandbox Code Playgroud)

试试这个,我几乎可以保证你会看到一个巨大的加速.


Klu*_*uge 6

ORDER BY如果数据库可以找到与ORDER BY表达式对应的索引,则通常不会很慢.

但是,您的SQL语句可能包含强制数据库在返回结果之前扫描整个表的其他内容,例如 SELECT TOP n

  • 通过"扫描整个数据库"的意思是"扫描整个*表*"? (3认同)

Qua*_*noi 6

如果你的过滤器看起来像这样:

WHERE col1 = @value1
      AND col2 = @value2
      AND col3 = @value3
ORDER BY
      col4
Run Code Online (Sandbox Code Playgroud)

,那么您需要在 上创建索引(col1, col2, col3, col4)

优化器将使用索引来过滤前三个值并按第四个值进行排序。

如果您没有这样的索引,则会发生以下情况之一:

  1. 优化器将使用索引来过滤条件WHERE,但它仍然需要ORDER剩余的行。
  2. 优化器将使用值的索引ORDER,但需要查看所有值以将其过滤掉。
  3. 优化器根本不会使用索引,因此 2“需要查看所有值以将其过滤掉”和 1“必须对所有剩余行进行排序”的两个缺点都是正确的。


Kap*_*psh 1

昨晚我在一个生产型数据库(不是开发人员数据库)上做了一些性能测试,这是我发现的:

表 A 中的总行数:13000

表 B 中的总行数:5000

连接查询返回的行数:5000

与 ORDER BY 子句一起使用所花费的时间:~5.422 秒

如果不使用 ORDER BY 子句,所花费的时间:~5.345 秒。

所以看起来 ORDER BY 并没有产生太大的影响。(我同意添加几毫秒)。

我还通过将所有 B.SYNTAX 值设置为 NULL 进行测试,以确保这不仅仅是传输如此多数据的网络延迟。

现在我从 SELECT 子句中删除了 B.SYNTAX,查询只花了 0.8 秒!

所以看起来整个 CLOB 列是瓶颈。这并不意味着我已经找到了使这个查询更快的解决方案,但至少我不会花时间编写排序算法。

感谢所有回复的人。我学到了很多东西,这让我尝试了一些不同的事情。