Ich liebe wirklich diese Art von Fragen, da Sie in Performance-Analyse tun können.
Zunächst erstellen wir eine Beispieldatenbank [test] mit einer [urls] -Tabelle mit einer Million zufälliger Datensätze.
Siehe Code unten.
-- Switch databases
USE [master];
go
-- Create simple database
CREATE DATABASE [test];
go
-- Switch databases
USE [test];
go
-- Create simple table
CREATE TABLE [urls]
(
my_id INT IDENTITY(1, 1)
PRIMARY KEY ,
my_link VARCHAR(255) ,
my_status VARCHAR(15)
);
go
-- http://stackoverflow.com/questions/1393951/what-is-the-best-way-to-create-and-populate-a-numbers-table
-- Load table with 1M rows of data
;
WITH PASS0
AS (SELECT 1 AS C
UNION ALL
SELECT 1
), --2 rows
PASS1
AS (SELECT 1 AS C
FROM PASS0 AS A ,
PASS0 AS B
), --4 rows
PASS2
AS (SELECT 1 AS C
FROM PASS1 AS A ,
PASS1 AS B
), --16 rows
PASS3
AS (SELECT 1 AS C
FROM PASS2 AS A ,
PASS2 AS B
), --256 rows
PASS4
AS (SELECT 1 AS C
FROM PASS3 AS A ,
PASS3 AS B
), --65536 rows
PASS5
AS (SELECT 1 AS C
FROM PASS4 AS A ,
PASS4 AS B
), --4,294,967,296 rows
TALLY
AS (SELECT ROW_NUMBER() OVER (ORDER BY C) AS Number
FROM PASS5
)
INSERT INTO urls
(my_link ,
my_status
)
SELECT
-- top 10 search engines + me
CASE (Number % 11)
WHEN 0 THEN 'www.ask.com'
WHEN 1 THEN 'www.bing.com'
WHEN 2 THEN 'www.duckduckgo.com'
WHEN 3 THEN 'www.dogpile.com'
WHEN 4 THEN 'www.webopedia.com'
WHEN 5 THEN 'www.clusty.com'
WHEN 6 THEN 'www.archive.org'
WHEN 7 THEN 'www.mahalo.com'
WHEN 8 THEN 'www.google.com'
WHEN 9 THEN 'www.yahoo.com'
ELSE 'www.craftydba.com'
END AS my_link ,
-- ratings scale
CASE (Number % 5)
WHEN 0 THEN 'poor'
WHEN 1 THEN 'fair'
WHEN 2 THEN 'good'
WHEN 3 THEN 'very good'
ELSE 'excellent'
END AS my_status
FROM TALLY AS T
WHERE Number <= 1000000
go
Zweitens möchten wir immer die Puffer löschen und zwischenspeichern, wenn wir in unserer Testumgebung eine Leistungsanalyse durchführen. Außerdem möchten wir Statistik-I/O und Zeit aktivieren, um die Ergebnisse zu vergleichen.
Siehe Code unten.
-- Show time & i/o
SET STATISTICS TIME ON
SET STATISTICS IO ON
GO
-- Remove clean buffers & clear plan cache
CHECKPOINT
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
GO
Drittens möchten wir die erste TSQL-Anweisung versuchen. Sehen Sie sich den Ausführungsplan an und erfassen Sie die Statistiken.
-- Try 1
SELECT * FROM urls ORDER BY my_status
/*
Table 'urls'. Scan count 5, logical reads 4987, physical reads 1, read-ahead reads 4918, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 3166 ms, elapsed time = 8130 ms.
*/
Viertens wollen wir die zweite TSQL Aussage versuchen. Vergessen Sie nicht, den Cache und die Puffer des Abfrageplans zu löschen. Wenn Sie dies nicht tun, dauert die Abfrage weniger als 1 Sekunde, da sich die meisten Informationen im Speicher befinden. Sehen Sie sich den Ausführungsplan an und erfassen Sie die Statistiken.
-- Try 2
SELECT ROW_NUMBER() OVER (ORDER BY my_status) as my_rownum, * FROM urls
/*
Table 'urls'. Scan count 5, logical reads 4987, physical reads 1, read-ahead reads 4918, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 3276 ms, elapsed time = 8414 ms.
*/
Last but not least, hier ist der spaßige Teil, die Leistungsanalyse.
1 - Wir können sehen, dass der zweite Plan ein Super-Set der ersten ist. Beide Pläne scannen also den Clustered Index und sortieren die Daten. Parallelität wird verwendet, um die Ergebnisse zusammenzufassen.
2 - Der zweite Plan/Abfrage muss die Zeilennummer berechnen. Er segmentiert die Daten und berechnet diesen Skalar. Daher enden zwei weitere Operatoren im Plan.
Es ist nicht verwunderlich, dass der erste Plan in 8130 ms und der zweite Plan in 8414 ms läuft.
Schauen Sie sich immer den Abfrageplan an. Sowohl geschätzt als auch aktuell. Sie sagen, dass Sie wollen, dass der Motor plant und was er tatsächlich tut.
In diesem Beispiel haben zwei verschiedene TSQL-Anweisungen fast identische Pläne.
Mit freundlichen Grüßen
John
www.craftydba.com
1. Nein 2. Der Mechanismus ist derselbe, aber das Ergebnis kann unterschiedlich sein Die tatsächliche Reihenfolge der Reihenfolge der ungeordneten Zeilen hängt von den Entscheidungen des Abfrageoptimierers ab und physisches Layout von Daten/Index – Arvo