1

すでにSELECT句にあるORDER句で計算またはサブクエリを使用すると、SQLはその列で並べ替えることを認識しますか?または、並べ替え時に各行のすべてを再計算しますか?

たとえば、次のようなひどいクエリを書いているとしましょう。

SELECT EmployeeName, (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID)
FROM Employee
ORDER BY (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID)

うん、私はこのクエリをよりよく書く方法を知っています、そして私は私の順序で序数を使用する方法を知っています-しかし私がそうでない場合はどうなりますか?SQLは行ごとにこのサブクエリを再実行しますか、それとも列2にすでにある値を使用できることを知っていますか?

関数を使用する列のORDERはどうですか?

SELECT EmployeeName, LTRIM(RTRIM(BranchName)) FROM Employee
ORDER BY LTRIM(RTRIM(BranchName))

並べ替えを行うためにBranchName列をリトリムしますか?

いくつかの実行プランを調べたところ、計算が追加されていないようですが、これが私の特定のケースではなく、一般性として当てはまるかどうかを確認したいと思いました。

私が尋ねる主な理由は、などのウィンドウ操作を実行するときにROWNUMBER() OVER(ORDER BY EmployeeID)、の序数参照を使用できないことORDER BYです。そのため、列の1つが複雑な場合は、それをテーブル変数にダンプしてから再度並べ替えることについて議論することがあります。

4

2 に答える 2

1

並べ替えは1回だけ実行され、エンジン自体は列に指定したエイリアス名で並べ替えることができます

SELECT EmployeeName, (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID)
FROM Employee
ORDER BY (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID)

次のように表現することもできます

SELECT EmployeeName, (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID) MyField
FROM Employee
ORDER BY myField

エンジンは基本的に同じことを行い、orderby句で使用するために列に一時的な名前を付けます。

于 2009-10-08T13:38:28.870 に答える
1

select count(*)のテーブルは2回スキャンされます。注文用に1回、選択用に1回。両方のサブクエリなどでトップ100を使用して、何が起こるかを確認することで、さらに遊ぶことができます。クエリが生成する論理読み取りの数を確認します。

あなたはこのクエリでそれを見ることができます:

SET STATISTICS IO ON 

USE AdventureWorks
GO

SELECT  (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = SOH.SalesOrderID) AS c, *
FROM    Sales.SalesOrderHeader SOH
ORDER by (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = SOH.SalesOrderID) desc
GO

SELECT  (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = SOH.SalesOrderID) AS c, *
FROM    Sales.SalesOrderHeader SOH
ORDER BY 1 desc
于 2009-10-08T14:41:19.053 に答える