100% found this document useful (1 vote)
32 views75 pages

(Ebook) Pro SQL Server 2022 Wait Statistics: A Practical Guide to Analyzing Performance in SQL Server and Azure SQL Database, 3rd Edition by Thomas LaRock, Enrico van de Laar ISBN 9781484287705, 1484287703 - The newest ebook version is ready, download now to explore

The document promotes instant access to various SQL Server-related ebooks available for download at ebooknice.com. It features titles such as 'Pro SQL Server 2022 Wait Statistics' and 'SQL Server Execution Plans', providing ISBN numbers and links for each ebook. Users can download in multiple formats and start reading on any device immediately.

Uploaded by

terezzsavski
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
32 views75 pages

(Ebook) Pro SQL Server 2022 Wait Statistics: A Practical Guide to Analyzing Performance in SQL Server and Azure SQL Database, 3rd Edition by Thomas LaRock, Enrico van de Laar ISBN 9781484287705, 1484287703 - The newest ebook version is ready, download now to explore

The document promotes instant access to various SQL Server-related ebooks available for download at ebooknice.com. It features titles such as 'Pro SQL Server 2022 Wait Statistics' and 'SQL Server Execution Plans', providing ISBN numbers and links for each ebook. Users can download in multiple formats and start reading on any device immediately.

Uploaded by

terezzsavski
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 75

Instant Ebook Access, One Click Away – Begin at ebooknice.

com

(Ebook) Pro SQL Server 2022 Wait Statistics: A


Practical Guide to Analyzing Performance in SQL
Server and Azure SQL Database, 3rd Edition by
Thomas LaRock, Enrico van de Laar ISBN
9781484287705, 1484287703
https://ebooknice.com/product/pro-sql-server-2022-wait-
statistics-a-practical-guide-to-analyzing-performance-in-
sql-server-and-azure-sql-database-3rd-edition-47559882

OR CLICK BUTTON

DOWLOAD EBOOK

Get Instant Ebook Downloads – Browse at https://ebooknice.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Start reading on any device today!

(Ebook) Pro SQL Server 2022 Wait Statistics: A Practical Guide to Analyzing
Performance in SQL Server and Azure SQL Database, 3rd Edition by Thomas LaRock,
Enrico van de Laar ISBN 9781484287712, 1484287711

https://ebooknice.com/product/pro-sql-server-2022-wait-statistics-a-practical-
guide-to-analyzing-performance-in-sql-server-and-azure-sql-database-3rd-
edition-47559896

ebooknice.com

(Ebook) Pro SQL Server 2019 Wait Statistics: A Practical Guide to Analyzing
Performance in SQL Server - Second Edition by Enrico van de Laar ISBN 9781484249161,
148424916X

https://ebooknice.com/product/pro-sql-server-2019-wait-statistics-a-practical-
guide-to-analyzing-performance-in-sql-server-second-edition-52952162

ebooknice.com

(Ebook) SQL Server Execution Plans. For SQL Server 2008 through to 2017 and Azure
SQL Database by Grant Fritchey ISBN 9781910035221, 191003522X

https://ebooknice.com/product/sql-server-execution-plans-for-sql-
server-2008-through-to-2017-and-azure-sql-database-11063662

ebooknice.com

(Ebook) Expert Performance Indexing in Azure SQL and SQL Server 2022 by Edward
Pollack, Jason Strate ISBN 9781484292150, 1484292154

https://ebooknice.com/product/expert-performance-indexing-in-azure-sql-and-sql-
server-2022-48211984

ebooknice.com
(Ebook) Practical Database Auditing for Microsoft SQL Server and Azure SQL:
Troubleshooting, Regulatory Compliance, and Governance by Josephine Bush ISBN
9781484286333, 1484286332

https://ebooknice.com/product/practical-database-auditing-for-microsoft-sql-
server-and-azure-sql-troubleshooting-regulatory-compliance-and-
governance-46188488

ebooknice.com

(Ebook) SQL Server Big Data Clusters : Data Virtualization, Data Lake, and AI
Platform by Benjamin Weissman, Enrico van de Laar ISBN 9781484259849, 9781484259856,
148425984X, 1484259858

https://ebooknice.com/product/sql-server-big-data-clusters-data-virtualization-
data-lake-and-ai-platform-22474702

ebooknice.com

(Ebook) Azure SQL Revealed: A Guide to the Cloud for SQL Server Professionals by Bob
Ward ISBN 9781484259313, 1484259319

https://ebooknice.com/product/azure-sql-revealed-a-guide-to-the-cloud-for-sql-
server-professionals-12286544

ebooknice.com

(Ebook) Azure SQL Revealed: A Guide to the Cloud for SQL Server Professionals by Bob
Ward ISBN 9781484259306, 1484259300

https://ebooknice.com/product/azure-sql-revealed-a-guide-to-the-cloud-for-sql-
server-professionals-12286546

ebooknice.com

(Ebook) Healthy SQL: A Comprehensive Guide to Healthy SQL Server Performance by


Robert Pearl ISBN 9781430267737, 1430267739

https://ebooknice.com/product/healthy-sql-a-comprehensive-guide-to-healthy-sql-
server-performance-5108072

ebooknice.com
Pro
SQL Server 2022
Wait Statistics
A Practical Guide to Analyzing Performance
in SQL Server and Azure SQL Database

Third Edition

Thomas LaRock
Enrico van de Laar
Pro SQL Server 2022
Wait Statistics
A Practical Guide to Analyzing
Performance in SQL Server and Azure
SQL Database
Third Edition

Thomas LaRock
Enrico van de Laar
Pro SQL Server 2022 Wait Statistics: A Practical Guide to Analyzing Performance in
SQL Server and Azure SQL Database
Thomas LaRock Enrico van de Laar
East Longmeadow, MA, USA Drachten, The Netherlands

ISBN-13 (pbk): 978-1-4842-8770-5 ISBN-13 (electronic): 978-1-4842-8771-2


https://doi.org/10.1007/978-1-4842-8771-2
Copyright © 2023 by Thomas LaRock, Enrico van de Laar
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Jonathan Gennick
Development Editor: Laura Berendson
Coordinating Editor: Jill Balzano
Cover designed by eStudioCalamar
Cover Photo by Almas Salakhov on Unsplash
Distributed to the book trade worldwide by Springer Science+Business Media New York, 1 New York Plaza,
Suite 4600, New York, NY 10004-1562, USA. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@
springer-sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole
member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc
is a Delaware corporation.
For information on translations, please e-mail [email protected]; for reprint,
paperback, or audio rights, please e-mail [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub (https://github.com/Apress). For more detailed information, please visit http://www.
apress.com/source-code.
Printed on acid-free paper
This book is dedicated to all the accidental database administrators,
developers, and anyone who has written a database query and
wondered “what the hell is taking so long?”
Also, for Roy, Moss, and anyone else who decided to turn
it off and back on again.
Table of Contents
About the Authors����������������������������������������������������������������������������������������������������xv

About the Technical Reviewers�����������������������������������������������������������������������������xvii


Acknowledgments��������������������������������������������������������������������������������������������������xix

Introduction������������������������������������������������������������������������������������������������������������xxi

Part I: Foundations of Wait Statistics Analysis����������������������������������������������� 1


Chapter 1: Wait Statistics Internals�������������������������������������������������������������������������� 3
A Brief History of Wait Statistics��������������������������������������������������������������������������������������������������� 4
The SQLOS������������������������������������������������������������������������������������������������������������������������������������ 6
Schedulers, Tasks, and Worker Threads���������������������������������������������������������������������������������������� 9
Sessions�������������������������������������������������������������������������������������������������������������������������������� 10
Requests�������������������������������������������������������������������������������������������������������������������������������� 12
Tasks������������������������������������������������������������������������������������������������������������������������������������� 12
Worker Threads��������������������������������������������������������������������������������������������������������������������� 14
Schedulers����������������������������������������������������������������������������������������������������������������������������� 17
Putting It All Together������������������������������������������������������������������������������������������������������������ 19
Wait Statistics������������������������������������������������������������������������������������������������������������������������ 20
Summary������������������������������������������������������������������������������������������������������������������������������� 25

Chapter 2: Querying SQL Server Wait Statistics����������������������������������������������������� 27


sys.dm_os_wait_stats���������������������������������������������������������������������������������������������������������������� 28
sys.dm_os_waiting_tasks���������������������������������������������������������������������������������������������������������� 31
Understanding sys.dm_os_waiting_tasks���������������������������������������������������������������������������� 31
Querying sys.dm_os_waiting_tasks������������������������������������������������������������������������������������� 33

v
Table of Contents

sys.dm_exec_requests��������������������������������������������������������������������������������������������������������������� 35
Understanding sys.dm_exec_requests��������������������������������������������������������������������������������� 35
Querying sys.dm_exec_requests������������������������������������������������������������������������������������������ 36
sys.dm_exec_session_wait_stats���������������������������������������������������������������������������������������������� 38
Combining DMVs to Detect Waits Happening Now��������������������������������������������������������������������� 40
Viewing Wait Statistics Using Perfmon��������������������������������������������������������������������������������������� 45
Capturing Wait Statistics Using Extended Events����������������������������������������������������������������������� 47
Capture Wait Statistics Information for a Specific Query������������������������������������������������������ 49
Analyzing Wait Statistics on a Per-Query Basis Using Execution Plans�������������������������������������� 59
Summary������������������������������������������������������������������������������������������������������������������������������������ 63

Chapter 3: The Query Store������������������������������������������������������������������������������������� 65


What Is the Query Store?������������������������������������������������������������������������������������������������������������ 65
Enabling the Query Store������������������������������������������������������������������������������������������������������������ 66
Enable the Query Store Using SSMS������������������������������������������������������������������������������������� 66
Enable the Query Store Using T-SQL������������������������������������������������������������������������������������� 68
Query Store Architecture������������������������������������������������������������������������������������������������������������� 68
How Wait Statistics Are Processed in the Query Store��������������������������������������������������������������� 69
Accessing Wait Statistics Through Query Store Reports������������������������������������������������������������� 72
Accessing Wait Statistics Through Query Store DMVs���������������������������������������������������������������� 75
Summary������������������������������������������������������������������������������������������������������������������������������������ 78

Chapter 4: Building a Solid Baseline���������������������������������������������������������������������� 79


What Are Baselines?������������������������������������������������������������������������������������������������������������������� 80
Visualizing Your Baselines���������������������������������������������������������������������������������������������������������� 82
Baseline Types and Statistics������������������������������������������������������������������������������������������������������ 83
Baseline Pitfalls�������������������������������������������������������������������������������������������������������������������������� 85
Too Much Information������������������������������������������������������������������������������������������������������������ 85
Know Your Metrics����������������������������������������������������������������������������������������������������������������� 85
Find the Big Measurement Changes������������������������������������������������������������������������������������� 85
Use Fixed Intervals���������������������������������������������������������������������������������������������������������������� 86

vi
Table of Contents

Building a Baseline for Wait Statistics Analysis�������������������������������������������������������������������������� 86


Reset Capture Method����������������������������������������������������������������������������������������������������������� 90
Delta Capture Method������������������������������������������������������������������������������������������������������������ 91
Using SQL Server Agent to Schedule Measurements����������������������������������������������������������������� 93
Wait Statistics Baseline Analysis������������������������������������������������������������������������������������������������ 96
Summary���������������������������������������������������������������������������������������������������������������������������������� 104

Part II: Wait Types��������������������������������������������������������������������������������������� 105


Chapter 5: CPU-Related Wait Types���������������������������������������������������������������������� 107
CXPACKET��������������������������������������������������������������������������������������������������������������������������������� 107
What Is the CXPACKET Wait Type?��������������������������������������������������������������������������������������� 108
Lowering CXPACKET Wait Time by Tuning the Parallelism Configuration Options��������������� 112
Lowering CXPACKET Wait Time by Resolving Skewed Workloads��������������������������������������� 116
Introduction of the CXCONSUMER Wait Type����������������������������������������������������������������������� 117
CXPACKET Summary����������������������������������������������������������������������������������������������������������� 118
SOS_SCHEDULER_YIELD����������������������������������������������������������������������������������������������������������� 118
What Is the SOS_SCHEDULER_YIELD Wait Type?���������������������������������������������������������������� 119
Lowering SOS_SCHEDULER_YIELD Waits���������������������������������������������������������������������������� 122
SOS_SCHEDULER_YIELD Summary������������������������������������������������������������������������������������� 127
THREADPOOL���������������������������������������������������������������������������������������������������������������������������� 127
What Is the THREADPOOL Wait Type?���������������������������������������������������������������������������������� 128
THREADPOOL Example�������������������������������������������������������������������������������������������������������� 130
Gaining Access to Our SQL Server During THREADPOOL Waits������������������������������������������� 134
Lowering THREADPOOL Waits Caused by Parallelism��������������������������������������������������������� 135
Lowering THREADPOOL Waits Caused by User Connections����������������������������������������������� 137
THREADPOOL Summary������������������������������������������������������������������������������������������������������ 140

Chapter 6: IO-Related Wait Types������������������������������������������������������������������������� 141


ASYNC_IO_COMPLETION����������������������������������������������������������������������������������������������������������� 141
What Is the ASYNC_IO_COMPLETION Wait Type?���������������������������������������������������������������� 142
ASYNC_IO_COMPLETION Example�������������������������������������������������������������������������������������� 143

vii
Table of Contents

Lowering ASYNC_IO_COMPLETION Waits���������������������������������������������������������������������������� 144


ASYNC_IO_COMPLETION Summary������������������������������������������������������������������������������������� 149
ASYNC_NETWORK_IO��������������������������������������������������������������������������������������������������������������� 150
What Is the ASYNC_NETWORK_IO Wait Type?��������������������������������������������������������������������� 150
ASYNC_NETWORK_IO Example������������������������������������������������������������������������������������������� 151
Lowering ASYNC_NETWORK_IO Waits��������������������������������������������������������������������������������� 152
ASYNC_NETWORK_IO Summary������������������������������������������������������������������������������������������ 153
CMEMTHREAD��������������������������������������������������������������������������������������������������������������������������� 154
What Is the CMEMTHREAD Wait Type?�������������������������������������������������������������������������������� 154
Lowering CMEMTHREAD Waits�������������������������������������������������������������������������������������������� 156
CMEMTHREAD Summary����������������������������������������������������������������������������������������������������� 157
IO_COMPLETION������������������������������������������������������������������������������������������������������������������������ 157
What Is the IO_COMPLETION Wait Type?����������������������������������������������������������������������������� 157
IO_COMPLETION Example��������������������������������������������������������������������������������������������������� 158
Lowering IO_COMPLETION Waits����������������������������������������������������������������������������������������� 159
IO_COMPLETION Summary�������������������������������������������������������������������������������������������������� 159
LOGBUFFER and WRITELOG������������������������������������������������������������������������������������������������������� 160
What Are the LOGBUFFER and WRITELOG Wait Types?�������������������������������������������������������� 160
LOGBUFFER and WRITELOG Example���������������������������������������������������������������������������������� 162
Lowering LOGBUFFER and WRITELOG Waits������������������������������������������������������������������������ 164
LOGBUFFER and WRITELOG Summary��������������������������������������������������������������������������������� 165
RESOURCE_SEMAPHORE���������������������������������������������������������������������������������������������������������� 165
What Is the RESOURCE_SEMAPHORE Wait Type?���������������������������������������������������������������� 165
RESOURCE_SEMAPHORE Example�������������������������������������������������������������������������������������� 167
Lowering RESOURCE_SEMAPHORE Waits��������������������������������������������������������������������������� 172
RESOURCE_SEMAPHORE Summary������������������������������������������������������������������������������������ 172
RESOURCE_SEMAPHORE_QUERY_COMPILE����������������������������������������������������������������������������� 173
What Is the RESOURCE_SEMAPHORE_QUERY_COMPILE Wait Type?���������������������������������� 173
RESOURCE_SEMAPHORE_QUERY_COMPILE Example��������������������������������������������������������� 177
Lowering RESOURCE_SEMAPHORE_QUERY_COMPILE Waits���������������������������������������������� 180
RESOURCE_SEMAPHORE_QUERY_COMPILE Summary������������������������������������������������������� 181

viii
Table of Contents

SLEEP_BPOOL_FLUSH�������������������������������������������������������������������������������������������������������������� 181
What Is the SLEEP_BPOOL_FLUSH Wait Type?�������������������������������������������������������������������� 181
SLEEP_BPOOL_FLUSH Example������������������������������������������������������������������������������������������ 184
Lowering SLEEP_BPOOL_FLUSH Waits������������������������������������������������������������������������������� 186
SLEEP_BPOOL_FLUSH Summary���������������������������������������������������������������������������������������� 187
WRITE_COMPLETION����������������������������������������������������������������������������������������������������������������� 187
What Is the WRITE_COMPLETION Wait Type?���������������������������������������������������������������������� 187
WRITE_COMPLETION Example��������������������������������������������������������������������������������������������� 188
Lowering WRITE_COMPLETION Waits���������������������������������������������������������������������������������� 188
WRITE_COMPLETION Summary������������������������������������������������������������������������������������������� 189

Chapter 7: Backup-Related Wait Types����������������������������������������������������������������� 191


BACKUPBUFFER������������������������������������������������������������������������������������������������������������������������ 192
What Is the BACKUPBUFFER Wait Type?������������������������������������������������������������������������������ 192
BACKUPBUFFER Example���������������������������������������������������������������������������������������������������� 195
Lowering BACKUPBUFFER Waits����������������������������������������������������������������������������������������� 195
BACKUPBUFFER Summary�������������������������������������������������������������������������������������������������� 197
BACKUPIO���������������������������������������������������������������������������������������������������������������������������������� 197
What Is the BACKUPIO Wait Type?��������������������������������������������������������������������������������������� 197
BACKUPIO Example������������������������������������������������������������������������������������������������������������� 198
Lowering BACKUPIO Waits��������������������������������������������������������������������������������������������������� 199
BACKUPIO Summary������������������������������������������������������������������������������������������������������������ 200
BACKUPTHREAD������������������������������������������������������������������������������������������������������������������������ 200
What Is the BACKUPTHREAD Wait Type?����������������������������������������������������������������������������� 200
BACKUPTHREAD Example���������������������������������������������������������������������������������������������������� 201
Lowering BACKUPTHREAD Waits����������������������������������������������������������������������������������������� 202
BACKUPTHREAD Summary�������������������������������������������������������������������������������������������������� 203

Chapter 8: Lock-Related Wait Types��������������������������������������������������������������������� 205


Introduction to Locking and Blocking��������������������������������������������������������������������������������������� 207
Lock Modes and Compatibility�������������������������������������������������������������������������������������������� 207
Locking Hierarchy���������������������������������������������������������������������������������������������������������������� 209

ix
Table of Contents

Isolation Levels�������������������������������������������������������������������������������������������������������������������� 211


Querying Lock Information�������������������������������������������������������������������������������������������������� 214
LCK_M_S���������������������������������������������������������������������������������������������������������������������������������� 217
What Is the LCK_M_S Wait Type?���������������������������������������������������������������������������������������� 218
LCK_M_S Example�������������������������������������������������������������������������������������������������������������� 218
Lowering LCK_M_S Waits��������������������������������������������������������������������������������������������������� 220
LCK_M_S Summary������������������������������������������������������������������������������������������������������������ 220
LCK_M_U���������������������������������������������������������������������������������������������������������������������������������� 221
What Is the LCK_M_U Wait Type?���������������������������������������������������������������������������������������� 221
LCK_M_U Example�������������������������������������������������������������������������������������������������������������� 223
Lowering LCK_M_U Waits��������������������������������������������������������������������������������������������������� 224
LCK_M_U Summary������������������������������������������������������������������������������������������������������������ 224
LCK_M_X���������������������������������������������������������������������������������������������������������������������������������� 225
What Is the LCK_M_X Wait Type?���������������������������������������������������������������������������������������� 225
LCK_M_X Example�������������������������������������������������������������������������������������������������������������� 225
Lowering LCK_M_X Waits���������������������������������������������������������������������������������������������������� 227
LCK_M_X Summary������������������������������������������������������������������������������������������������������������� 227
LCK_M_I[xx]������������������������������������������������������������������������������������������������������������������������������ 227
What Is the LCK_M_I[xx] Wait Type?����������������������������������������������������������������������������������� 227
LCK_M_I[xx] Example���������������������������������������������������������������������������������������������������������� 228
Lowering LCK_M_I[xx] Waits����������������������������������������������������������������������������������������������� 230
LCK_M_I[xx] Summary�������������������������������������������������������������������������������������������������������� 230
LCK_M_SCH_S and LCK_M_SCH_M����������������������������������������������������������������������������������������� 231
What Are the LCK_M_SCH_S and LCK_M_SCH_M Wait Types?������������������������������������������ 231
LCK_M_SCH_S and LCK_M_SCH_M Example�������������������������������������������������������������������� 232
Lowering LCK_M_SCH_S and LCK_M_SCH_M Waits���������������������������������������������������������� 234
LCK_M_SCH_S and LCK_M_SCH_M Summary������������������������������������������������������������������� 234

Chapter 9: Latch-Related Wait Types�������������������������������������������������������������������� 235


Introduction to Latches������������������������������������������������������������������������������������������������������������� 235
Latch Modes������������������������������������������������������������������������������������������������������������������������ 237
Latch Waits�������������������������������������������������������������������������������������������������������������������������� 238

x
Table of Contents

sys.dm_os_latch_stats������������������������������������������������������������������������������������������������������� 240
Page-Latch Contention�������������������������������������������������������������������������������������������������������� 241
PAGELATCH_[xx]����������������������������������������������������������������������������������������������������������������������� 244
What Is the PAGELATCH_[xx] Wait Type?����������������������������������������������������������������������������� 244
PAGELATCH_[xx] Example��������������������������������������������������������������������������������������������������� 245
Lowering PAGELATCH_[xx] Waits����������������������������������������������������������������������������������������� 250
PAGELATCH_[xx] Summary�������������������������������������������������������������������������������������������������� 255
LATCH_[xx]�������������������������������������������������������������������������������������������������������������������������������� 256
What Is the LATCH_[xx] Wait Type?������������������������������������������������������������������������������������� 256
LATCH_[xx] Example������������������������������������������������������������������������������������������������������������ 257
Lowering LATCH_[xx] Waits������������������������������������������������������������������������������������������������� 262
LATCH_[xx] Summary���������������������������������������������������������������������������������������������������������� 263
PAGEIOLATCH_[xx]�������������������������������������������������������������������������������������������������������������������� 263
What Is the PAGEIOLATCH_[xx] Wait Type?�������������������������������������������������������������������������� 264
PAGEIOLATCH_[xx] Example������������������������������������������������������������������������������������������������ 266
Lowering PAGEIOLATCH_[xx] Waits������������������������������������������������������������������������������������� 268
PAGEIOLATCH_[xx] Summary���������������������������������������������������������������������������������������������� 272

Chapter 10: High-Availability and Disaster-Recovery Wait Types������������������������ 273


DBMIRROR_SEND��������������������������������������������������������������������������������������������������������������������� 274
What Is the DBMIRROR_SEND Wait Type?��������������������������������������������������������������������������� 277
DBMIRROR_SEND Example������������������������������������������������������������������������������������������������� 277
Lowering DBMIRROR_SEND Waits��������������������������������������������������������������������������������������� 279
DBMIRROR_SEND Summary������������������������������������������������������������������������������������������������ 280
HADR_LOGCAPTURE_WAIT and HADR_WORK_QUEUE�������������������������������������������������������������� 281
What Are the HADR_LOGCAPTURE_WAIT and HADR_WORK_QUEUE Wait Types?��������������� 281
HADR_LOGCAPTURE_WAIT and HADR_WORK_QUEUE Summary���������������������������������������� 284
HADR_SYNC_COMMIT��������������������������������������������������������������������������������������������������������������� 284
What Is the HADR_SYNC_COMMIT Wait Type?�������������������������������������������������������������������� 284
HADR_SYNC_COMMIT Example������������������������������������������������������������������������������������������ 285
Lowering HADR_SYNC_COMMIT Waits�������������������������������������������������������������������������������� 288
HADR_SYNC_COMMIT Summary����������������������������������������������������������������������������������������� 291

xi
Table of Contents

REDO_THREAD_PENDING_WORK���������������������������������������������������������������������������������������������� 292
What Is the REDO_THREAD_PENDING_WORK Wait Type?��������������������������������������������������� 292
REDO_THREAD_PENDING_WORK Summary������������������������������������������������������������������������ 294

Chapter 11: Preemptive Wait Types���������������������������������������������������������������������� 295


SQL Server on Linux������������������������������������������������������������������������������������������������������������������ 296
PREEMPTIVE_OS_ENCRYPTMESSAGE and PREEMPTIVE_OS_DECRYPTMESSAGE������������������� 299
What Are the PREEMPTIVE_OS_ENCRYPTMESSAGE and PREEMPTIVE_OS_
DECRYPTMESSAGE Wait Types?������������������������������������������������������������������������������������������ 299
PREEMPTIVE_OS_ENCRYPTMESSAGE and PREEMPTIVE_OS_DECRYPTMESSAGE
Example������������������������������������������������������������������������������������������������������������������������������� 299
Lowering PREEMPTIVE_OS_ENCRYPTMESSAGE and PREEMPTIVE_OS_
DECRYPTMESSAGE Waits���������������������������������������������������������������������������������������������������� 307
PREEMPTIVE_OS_ENCRYPTMESSAGE and PREEMPTIVE_OS_DECRYPTMESSAGE
Summary����������������������������������������������������������������������������������������������������������������������������� 307
PREEMPTIVE_OS_WRITEFILEGATHER��������������������������������������������������������������������������������������� 307
What Is the PREEMPTIVE_OS_WRITEFILEGATHER Wait Type?��������������������������������������������� 307
PREEMPTIVE_OS_WRITEFILEGATHER Example������������������������������������������������������������������� 308
Lowering PREEMPTIVE_OS_WRITEFILEGATHER Waits�������������������������������������������������������� 309
PREEMPTIVE_OS_WRITEFILEGATHER Summary������������������������������������������������������������������ 310
PREEMPTIVE_OS_AUTHENTICATIONOPS����������������������������������������������������������������������������������� 311
What Is the PREEMPTIVE_OS_AUTHENTICATIONOPS Wait Type?���������������������������������������� 311
PREEMPTIVE_OS_AUTHENTICATIONOPS Example��������������������������������������������������������������� 312
Lowering PREEMPTIVE_OS_AUTHENTICATIONOPS Waits���������������������������������������������������� 314
PREEMPTIVE_OS_AUTHENTICATIONOPS Summary������������������������������������������������������������� 316
PREEMPTIVE_OS_GETPROCADDRESS��������������������������������������������������������������������������������������� 316
What Is the PREEMPTIVE_OS_GETPROCADDRESS Wait Type?�������������������������������������������� 316
PREEMPTIVE_OS_GETPROCADDRESS Example������������������������������������������������������������������ 319
Lowering PREEMPTIVE_OS_GETPROCADDRESS Waits�������������������������������������������������������� 320
PREEMPTIVE_OS_GETPROCADDRESS Summary����������������������������������������������������������������� 320

xii
Table of Contents

Chapter 12: Background and Miscellaneous Wait Types�������������������������������������� 321


CHECKPOINT_QUEUE����������������������������������������������������������������������������������������������������������������� 322
What Is the CHECKPOINT_QUEUE Wait Type?���������������������������������������������������������������������� 322
CHECKPOINT_QUEUE Summary������������������������������������������������������������������������������������������� 325
DIRTY_PAGE_POLL�������������������������������������������������������������������������������������������������������������������� 326
What Is the DIRTY_PAGE_POLL Wait Type?�������������������������������������������������������������������������� 326
DIRTY_PAGE_POLL Summary���������������������������������������������������������������������������������������������� 329
LAZYWRITER_SLEEP����������������������������������������������������������������������������������������������������������������� 329
What Is the LAZYWRITER_SLEEP Wait Type?����������������������������������������������������������������������� 329
LAZYWRITER_SLEEP Summary������������������������������������������������������������������������������������������� 331
MSQL_XP���������������������������������������������������������������������������������������������������������������������������������� 331
What Is the MSQL_XP Wait Type?���������������������������������������������������������������������������������������� 331
MSQL_XP Example�������������������������������������������������������������������������������������������������������������� 332
Lowering MSQL_XP Waits��������������������������������������������������������������������������������������������������� 333
MSQL_XP Summary������������������������������������������������������������������������������������������������������������ 334
OLEDB��������������������������������������������������������������������������������������������������������������������������������������� 334
What Is the OLEDB Wait Type?��������������������������������������������������������������������������������������������� 334
OLEDB Example������������������������������������������������������������������������������������������������������������������� 334
Lowering OLEDB Waits�������������������������������������������������������������������������������������������������������� 335
OLEDB Summary����������������������������������������������������������������������������������������������������������������� 336
TRACEWRITE����������������������������������������������������������������������������������������������������������������������������� 336
What Is the TRACEWRITE Wait Type?����������������������������������������������������������������������������������� 337
TRACEWRITE Example��������������������������������������������������������������������������������������������������������� 337
Lowering TRACEWRITE Waits���������������������������������������������������������������������������������������������� 341
TRACEWRITE Summary������������������������������������������������������������������������������������������������������� 344
WAITFOR����������������������������������������������������������������������������������������������������������������������������������� 344
What Is the WAITFOR Wait Type?����������������������������������������������������������������������������������������� 345
WAITFOR Example��������������������������������������������������������������������������������������������������������������� 345
WAITFOR Summary�������������������������������������������������������������������������������������������������������������� 346

xiii
Table of Contents

Chapter 13: In-Memory OLTP–Related Wait Types������������������������������������������������ 347


Introduction to In-Memory OLTP����������������������������������������������������������������������������������������������� 347
Checkpoint File Pairs (CFPs)������������������������������������������������������������������������������������������������ 348
Isolation������������������������������������������������������������������������������������������������������������������������������� 352
Transaction Log Changes���������������������������������������������������������������������������������������������������� 352
WAIT_XTP_HOST_WAIT������������������������������������������������������������������������������������������������������������� 353
What Is the WAIT_XTP_HOST_WAIT Wait Type?������������������������������������������������������������������� 353
WAIT_XTP_HOST_WAIT Summary��������������������������������������������������������������������������������������� 356
WAIT_XTP_CKPT_CLOSE����������������������������������������������������������������������������������������������������������� 357
What Is the WAIT_XTP_CKPT_CLOSE Wait Type?���������������������������������������������������������������� 357
WAIT_XTP_CKPT_CLOSE Summary������������������������������������������������������������������������������������� 358
WAIT_XTP_OFFLINE_CKPT_NEW_LOG�������������������������������������������������������������������������������������� 359
What Is the WAIT_XTP_OFFLINE_CKPT_NEW_LOG Wait Type?�������������������������������������������� 359
WAIT_XTP_OFFLINE_CKPT_NEW_LOG Summary���������������������������������������������������������������� 360

Appendix I: Example SQL Server Machine Configurations������������������������������������ 361

Appendix II: Spinlocks������������������������������������������������������������������������������������������ 365

Appendix III: Latch Classes���������������������������������������������������������������������������������� 369

Appendix IV: Waits and DMVs������������������������������������������������������������������������������� 381

Index��������������������������������������������������������������������������������������������������������������������� 391

xiv
About the Authors
Thomas LaRock has over 20 years of IT experience holding administrator roles. He is
a Microsoft Certified Master in SQL Server and a Microsoft Data Platform MVP since
2009. LaRock has spent much of his career working with data and databases, which led
to his selection as a Technical Advocate for Confio Software in 2010 for the software now
known as SolarWinds Database Performance Analyzer (DPA).
Currently, he serves as a Head Geek for SolarWinds, a company specializing in
software for enterprise infrastructure monitoring. This role allows for LaRock to work
with a variety of customers, helping to solve questions regarding network, application,
and database performance tuning and virtualization. You can reach Thomas through his
blog (thomaslarock.com/blog) and find him on Twitter (@SQLRockstar).

Enrico van de Laar has been working with data in various formats and sizes for over
15 years. He is a data and advanced analytics consultant for DataHeroes where he helps
organizations optimize their data platform environment and helps them with their first
steps in the world of advanced analytics. He is a Data Platform MVP since 2014 and a
frequent speaker on various data-related events throughout the world. He frequently
blogs about technologies such as Microsoft SQL Server and Azure Machine Learning on
his blog at enricovandelaar.com. You can contact Enrico on Twitter at @evdlaar.

xv
About the Technical Reviewers
Denny Cherry is the owner and principal consultant for
Denny Cherry & Associates Consulting and has over two
decades of experience working with platforms such as Azure,
Microsoft SQL Server, Hyper-V, vSphere, and Enterprise
Storage solutions. Denny’s areas of technical expertise
include system architecture, performance tuning, security,
replication, and troubleshooting. Denny currently holds
several of the Microsoft certifications related to SQL Server
for versions 2000 through 2017 including the Microsoft
Certified Master as well as being a Microsoft MVP for over
a decade. Denny has written several books and dozens of
technical articles on SQL Server management and how SQL
Server integrates with various other technologies.

Joseph D’Antoni is a Principal Consultant at Denny Cherry


& Associates Consulting. He is recognized as a VMWare
vExpert and a Microsoft Data Platform MVP and has over
20 years of experience working in both Fortune 500 and
smaller firms. He has worked extensively on database
platforms and cloud technologies and has specific expertise
in performance tuning, infrastructure, and disaster recovery.

xvii
Acknowledgments
There are many people to acknowledge and thank for helping me with this book. I’ll do
my best to include as many as I can, but please don’t be offended if I forget you; it’s not
on purpose.
I’ll start with my wife, Suzanne, for her patience as I spent many off-hours
completing this book. Oh, and for all the time I’ve spent away from home for the past
15 years.
Thanks to Bob Ward of Microsoft for helping uncover new SQL 2022 features, as well
as your willingness to share your knowledge on SQL Server for the past 25 years. And
thanks for your time in Barcelona in 2006 when you inspired me to want to learn more
about SQL Server.
Thanks to my partner in #TeamData, Karen Lopez, for your help, support, and
friendship for many years. I became a better technical writer and presenter by learning
from you.
Thanks to Kevin Kline for your guidance and support as I left my career as a
production DBA to become a Technical Advocate and for providing an example of what
proper community leadership looks like.
To Buck Woody, for your support in helping me understand my strengths and your
guidance in career opportunities through the years.
To Craig and Vinny, for giving me the opportunity to fail as a DBA, and to Frank and
Lori for not letting it happen as much as it should have.
To Rie, Betsy, Rochelle, and everyone on the Microsoft Community team for
awarding me the Microsoft MVP status all these years.
Finally, to Jonathan, for thinking of me when it came time to update this book for
SQL 2022. Thank you for the opportunity to write another book for you, 12 years later.

xix
Introduction
“Write the book you wish someone else would have written and handed to you when you
were starting as a DBA.”
Those words were spoken to me by my friend and mentor, Kevin Kline, roughly 13
years ago. At the time I was writing my first book, DBA Survivor, and I asked Kevin for
advice on how to approach the project. His answer gave me clarity, and I’ve used the
same approach for this book you are now reading.
At the time I started as a junior DBA, Tom Davidson’s well-known SQL Server 2005
Waits and Queues whitepaper was years away from publication. What I knew about waits
I would find using DBCC statements against (the artist formally known as) Sybase ASE
and SQL Server 2000 instances.
In other words, I didn’t know much.
With the release of SQL Server 2005 and the publication of the Davidson whitepaper,
wait statistics became a viable tuning methodology. Administrators and developers
could now use waits and queues to understand exactly why a query was running longer
than expected. Overnight our team transitioned from reacting to query performance
issues to being proactive in understanding which resources the overall database
workload needed most.
Every request sent to a database server has the same constraints: memory,
processing, disk, network, and locking/blocking. It doesn’t matter if you want to rely
solely on execution plans for query tuning; the physical and logical constraints for the
query remain the same: they are just presented differently in an execution plan. The
waits and queue tuning methodology reduces the complexity and time necessary for
query performance tuning by an order of magnitude.
Once you understand how the database engine processes requests, how waits
happen, and how to track them, you are well on your way to being an expert in query
performance tuning.
And that’s the goal of this book. When you are done reading, I want you to have all
the skills necessary to be an expert in query performance tuning. That’s the book I wish
someone would have written and handed to me when I was first starting as a DBA.

xxi
Introduction

To reach the goal, this book has been split into two unequal parts. Part I,
“Foundations of Wait Statistics Analysis,” provides details on how the database engine
processes a query (officially called a request, which is sent by a session, after a connection
to the instance is established) followed by information on how to query wait statistics
information through various SQL Server dynamic management views (DMVs). Part I
finishes with an overview of the Query Store feature and guidance on how to create and
gather metrics to build your own baselines.
Part II, “Wait Types,” dives into specific waits, the causes, some examples, and
possible resolutions. The chapters are divided by wait categories, which is a bit tricky
as some waits (such as PAGEIOLATCH) have overlap between more than one possible
constraint (memory and disk). Therefore, the chapters break down specific waits into
categories by CPU, IO, backups, locks, latches, high-availability and disaster-recovery,
preemptive, background and miscellaneous, and In-Memory OLTP.
Yes, waits for background and miscellaneous are included, despite their being
benign for query performance. It’s important for you to know why (and when) these
waits happen and when they are safe to ignore (they usually are, but not always).
One thing to note, the examples in this book use a database named GalacticWorks.
This is a modified version of AdventureWorks I use for a variety of demos when teaching
my classes. The examples in the book will work with AdventureWorks, so don’t panic
about not having GalacticWorks; you’ll be fine with most versions of AdventureWorks.
When you finish this book, I want you to have the confidence to tackle any query
performance tuning problem. You’ll have the details, information, and knowledge
necessary to be an expert. And maybe soon enough, you’ll be teaching others and maybe
someday write your own book, too.

xxii
PART I

Foundations of Wait
Statistics Analysis
CHAPTER 1

Wait Statistics Internals


SQL Server wait statistics are an important tool for analyzing performance-related
problems and optimizing SQL Server performance. However, they are not always
known to many database administrators or developers. I believe this has to do with their
relatively complex nature, the sheer volume of different types available, and the lack
of documentation for many types of wait statistics. Wait statistics are also directly tied
to the specific SQL Server on which they occur, meaning it is impossible to compare
wait statistics of Server A to wait statistics of Server B, even with identical hardware and
database configuration. Every configuration option, from the hardware firmware level
to the configuration of the SQL Server Native Client on the client computers, will impact
the wait statistics!
Therefore, we will start this book with a review of SQL Server internals pertaining to
wait statistics. We will discuss how wait events are generated, how to view wait events,
and how to analyze them as part of a proper performance tuning methodology. Then in
Part II of this book, we will explore and examine specific wait events.
This chapter will look at the history of wait statistics through the various versions of
SQL Server. Next, we will review the SQL Operating System, or SQLOS. The architecture
of the SQLOS is closely tied to wait statistics and to performance troubleshooting in
general. The rest of this chapter is dedicated to one of the most important aspects of wait
statistics: thread scheduling.
Before we begin, I want to mention a few things related to the terminology used
when discussing wait statistics. In the introduction of this book and the preceding
paragraphs, I mentioned the term wait statistics. The sentence “compare wait statistics
of Server A to wait statistics of Server B” is technically wrong, since we compare the
wait time (the total time we have been waiting on a resource) of a specific wait type (the
specific wait type related to the resource we are waiting on). From this point on, when I
use the term wait statistics, I mean the concept of wait statistics, and I will use the correct
terms wait time and wait type where appropriate.

3
© Thomas LaRock, Enrico van de Laar 2023
T. LaRock and E. van de Laar, Pro SQL Server 2022 Wait Statistics,
https://doi.org/10.1007/978-1-4842-8771-2_1
Chapter 1 Wait Statistics Internals

A Brief History of Wait Statistics


SQL Server has been around for quite some time now. The first release of SQL Server
dates back to 1989 and was released for the OS/2 platform. Until SQL Server 6.0, released
in 1995, Microsoft worked together with Sybase to develop SQL Server. In 1995, however,
Microsoft and Sybase went their separate ways. Both Microsoft and Sybase stayed active
in the database world (SAP acquired Sybase in 2010). In 2022, Microsoft will release
SQL Server 2022, while SAP released SAP Sybase ASE 16 in 2014 (but is still maintained
today), both relational enterprise-level database systems.
Between SQL Server 6.0 and SQL Server 2022, many things have changed, and it is
difficult to compare any two versions alongside one another. One thing which has not
changed through the years is the concept of wait statistics. Each version of SQL Server
stores information about its internal processes. Even though the way we access such
information has changed over the years, wait statistics remain an important part of the
internal logging process.
In early versions of SQL Server, access to wait statistics required the use of
undocumented commands. Figure 1-1 shows how to query wait statistics information in
SQL Server 6.5 using the DBCC command.

Figure 1-1. SQL Server wait statistics for SQL Server 6.5

4
Chapter 1 Wait Statistics Internals

One of the big changes introduced with SQL Server 2005 was the conversion of
many internal functions and commands into Dynamic Management Views (DMVs) and
Dynamic Management Functions (DMFs). This made it easier to query and analyze the
information returned by functions and commands, including wait statistics information.
A new way of performance analysis was born with the release of the SQL Server 2005
Microsoft whitepaper SQL Server 2005 Waits and Queues by Tom Davidson.
In the subsequent releases of SQL Server, the volume of new and different wait types
grew exponentially whenever new features or configuration options were introduced.
If you look at Figure 1-1, you will notice that 21 different wait types were returned.
Figure 1-2 shows the amount of wait types, as the number of rows returned, available in
SQL Server 2022.

Figure 1-2. SQL Server wait statistics in SQL Server 2022

5
Chapter 1 Wait Statistics Internals

With the release of SQL Server 2022 RC0, the number of wait types increased to more
than 1,300 different wait types! The number of wait types will likely continue to grow
in future SQL Server releases, as new features are introduced or existing features are
changed. Thankfully there is a lot more information available about wait statistics now
than there was in SQL Server 6.5!

The SQLOS
The world of computer hardware changes constantly. Every year, or in some cases
every month, we stuff more cores inside of processors, increase the memory capacity of
mainboards, or introduce entirely new hardware concepts like PCI-based persistent flash
storage. Database Management Systems (or DBMSs) are eager to take advantage of new
hardware trends. Because of the fast-changing nature of hardware and the need to utilize
new hardware options as soon as they become available, the SQL Server team decided to
change the SQL Server platform layer starting with SQL Server 2005.
Before SQL Server 2005, the platform layer of SQL Server was restricted, with many
operations performed by the operating system itself. This meant it was difficult for
SQL Server to keep up with the fast-changing world of server hardware, as changing a
complete operating system in order to utilize faster hardware or new hardware features
is a time-consuming and complex operation.
Figure 1-3 shows the (simplified) architecture of SQL Server before the introduction
of the SQLOS in SQL Server 2005.

6
Chapter 1 Wait Statistics Internals

Figure 1-3. SQL Server architecture before the introduction of SQLOS

SQL Server 2005 introduced one of the biggest changes to the SQL Server engine
seen to this day, the SQLOS. This is a completely new platform layer functioning as a
user-level operating system. The SQLOS has made it possible to fully utilize current
and future hardware and has enabled features like advanced parallelism. The SQLOS
is highly configurable and adjusts itself to the hardware it is running on, thus making it
perfectly scalable for high-end or low-end systems alike.
Figure 1-4 shows the (simplified) architecture of SQL Server 2005, including the
SQLOS layer.

7
Chapter 1 Wait Statistics Internals

Figure 1-4. SQL Server 2005 architecture

The SQLOS changed the way SQL Server accesses processor resources by
introducing schedulers, tasks, and worker threads. This gives the SQLOS greater control
of how work should be completed by the processors. The Windows operating system
uses a preemptive scheduling approach. This means that Windows will give every
process that needs processor time a priority and fixed slice of time, or a quantum. This
process priority is calculated from a number of variables like resource usage, expected
runtime, current activity, and so forth. By using preemptive scheduling, the Windows
operating system can choose to interrupt a process when a process with a higher priority
needs processor time. This way of scheduling can have a negative impact on processes
generated by SQL Server, since those processes could easily be interrupted by higher
priority ones, including those of other applications. For this reason, the SQLOS uses its
own (cooperative) non-preemptive scheduling mechanism, making sure that Windows
processes cannot interrupt SQLOS processes.

8
Chapter 1 Wait Statistics Internals

Nerd Note SQL Server 7 and SQL Server 2000 also used non-preemptive
scheduling using User Mode Scheduling (UMS). SQLOS brought many more system
components closer together, thus enabling better performance and scalability.

There are some exceptions when the SQLOS cannot use non-preemptive scheduling,
for instance, when the SQLOS needs to access a resource through the Windows
operating system. We will discuss these exceptions later in this book in Chapter 11,
“Preemptive Wait Types.”

Schedulers, Tasks, and Worker Threads


Because SQLOS uses a different method to execute requests than the Windows operating
system uses, SQL Server introduced a different way to schedule processor time using
schedulers, tasks, and worker threads. Figure 1-5 shows the different parts of SQL Server
scheduling and how they relate to each other.

9
Chapter 1 Wait Statistics Internals

Figure 1-5. SQL Server scheduling

Sessions
A session is the connection a client has to SQL Server after it has been successfully
authenticated. We can access session information by querying the sys.dm_exec_
sessions DMV using the following query:

SELECT *
FROM sys.dm_exec_sessions;

In older versions of SQL Server, user sessions had a session_id greater than 50;
everything lower was reserved for internal SQL Server processes. However, on very busy
servers, there was a possibility SQL Server needed to use a session_id greater than 50. If
you are only interested in information about user-initiated sessions, it is better to filter
the results of the sys.dm_exec_sessions DMV using the is_user_process column instead
of filtering on a session_id greater than 50. The following query will only return user
sessions and will filter out the internal system sessions:

10
Chapter 1 Wait Statistics Internals

SELECT *
FROM sys.dm_exec_sessions
WHERE is_user_process = 1;

Figure 1-6 shows a small part of the results of this query.

Figure 1-6. sys.dm_exec_sessions results

There are many columns returned by the sys.dm_exec_sessions DMV that provide
information about each session. Some of the more interesting columns include the
following:

host_process_id – The process ID or (PID) of the client program


connected to SQL Server will show NULL for internal sessions.

cpu_time – The amount of processor time (in milliseconds) the


session has used since it was first established.

memory_usage – The amount of memory (8k pages) used by the


session since it was first established.

reads – Number of reads performed by this session since it was


first established.
writes – Number of writes performed by this session since it was
first established.

row_count – Number of rows returned for this session up to


this point.

status – Possible values include “running,” “sleeping,” “dormant,”


and “preconnect.”

The most common values of the status column are “running,” which indicates that
one or more requests are currently being processed from this session, and “sleeping,”
which means no requests are currently being processed from this session.

11
Chapter 1 Wait Statistics Internals

Requests
A request is the SQL Server execution engine’s representation of a query submitted by a
session. Again, we will use a DMV to query information about a request; in this case, we
query the sys.dm_exec_requests DMV:

SELECT *
FROM sys.dm_exec_requests;

Figure 1-7 shows a portion of the results of this query.

Figure 1-7. sys.dm_exec_requests results

The sys.dm_exec_requests DMV is an incredibly powerful tool for troubleshooting


performance-related issues. This DMV has a lot of information about current queries
and helps detect performance bottlenecks relatively quickly. Because the sys.dm_exec_
requests DMV also displays wait statistics–related information, we will take a thorough
look at it in Chapter 2, “Querying SQL Server Wait Statistics.”

Tasks
Tasks represent the work to be performed by the SQLOS, but tasks do not perform any
work themselves. When a request is received by SQL Server, one or more tasks are

12
Chapter 1 Wait Statistics Internals

created to fulfill the request. The number of tasks generated for a request depends on if
the query request is being performed using parallelism or if it’s being run serially.
We will use the sys.dm_os_tasks DMV to query the task information:

SELECT *
FROM sys.dm_os_tasks;

Figure 1-8 shows a part of the results of the query.

Figure 1-8. sys.dm_os_tasks results

When you query the sys.dm_os_tasks DMV, you will discover it returns many results,
even on servers with little user activity. This is because SQL Server uses tasks for its own
processes as well.
There are some interesting columns in this DMV worth exploring to see the relations
between different DMVs:

session_id – The ID of the session which requested this task.

worker_address – The memory address of the worker thread


associated with this task.

task_address – The memory address of this task.

task_state – Possible values include “pending,” “runnable,”


“running,” “suspended,” “done,” and “spinloop.”

The most common values of the task_state column are “running,” “runnable,” and
“suspended.”

13
Chapter 1 Wait Statistics Internals

Worker Threads
Every task created has a worker thread assigned, and the worker thread then performs
the actions requested by the task.

Nerd Note A worker thread does not perform the work itself; instead it requests
a thread from the Windows operating system to perform the work. For the sake of
simplicity, and the fact the Windows thread runs outside the SQLOS, I have left this
step out of Figure 1-5. You can access information about the Windows operating
system threads by querying sys.dm_os_threads if you are interested.

When a task requests a worker thread, SQL Server will first look for an idle worker
thread to assign to the task. In the case when no idle worker thread is located and the
maximum number of worker threads has been reached, the request is queued until a
worker thread finishes its current work and becomes available.
There is a limit to the number of worker threads SQL Server has available for
processing requests. This number is automatically calculated and configured by SQL
Server during startup. We calculate the maximum number of worker threads ourselves
using these formulas:

32-bit system with <= 4 logical processors 256 worker threads


32-bit system with > 4 logical processors 256 + ((# of logical processors – 4) * 8)
64-bit system with <= 4 logical processors 512 worker threads
64-bit system with > 4 logical processors 512 + ((# of logical processors – 4) * 16)

Example: For a 64-bit system with 16 logical processors, we calculate the maximum
number of worker threads using the preceding formula:

512 + ((# of logical processors – 4) * 16) =


512 + ((16 – 4) * 16) =
512 + (12 * 16) =
512 + (192) = 704

which would assign a maximum of 704 worker threads.

14
Chapter 1 Wait Statistics Internals

The number of worker threads has a default of 0, allowing SQL Server to set the
number of max worker threads using the preceding formulas when it starts. We alter
the default by changing the max worker threads options in SQL Server’s properties, as
illustrated by Figure 1-9.

Figure 1-9. Processors page in the Server Properties

Generally speaking, you should not need to change the max worker threads option,
and my advice is to leave the setting alone, as it should only be changed in very specific
cases (I will discuss one of those potential cases in Chapter 5, “CPU-Related Wait Types,”
when we talk about THREADPOOL waits).

15
Chapter 1 Wait Statistics Internals

One thing to keep in mind is worker threads require memory to work. For 32-bit
systems, this is 512 KB for every worker thread; 64-bit systems will need 2048 KB for
every worker thread. Thus, changing the number of worker threads can potentially
impact the memory requirements of SQL Server. This does not mean you need a massive
amount of memory just for your worker threads – SQL Server will automatically destroy
idle worker threads after 15 minutes or if SQL Server is under heavy memory pressure.
SQL Server supplies us with a DMV to query information about the worker threads,
sys.dm_os_workers. Figure 1-10 shows some of the results of this query:

SELECT *
FROM sys.dm_os_workers;

Figure 1-10. Results of querying sys.dm_os_workers

The sys.dm_os_workers DMV is large and complex with many columns marked as
“Internal use only” by Microsoft. However, the columns task_address and scheduler_
address are available to link together the different DMVs we have discussed so far.
Worker threads iterate through different phases while exposed to the processor,
which we observe when we examine the state column in the sys.dm_os_workers DMV:

• ​​INIT – The worker thread is initialized by the SQLOS.


• RUNNING – The worker thread is currently performing work on a
processor.

16
Chapter 1 Wait Statistics Internals

• RUNNABLE – The worker thread is ready to run on a processor.

• SUSPENDED – The worker thread is waiting for a resource.

The states the worker threads go through while performing work is the main focus
of this book. Every time a worker thread is not in the “RUNNING” state, it has to wait,
and the SQLOS records this information giving us valuable insight into what the worker
thread has been waiting on and how long it has been waiting.

Schedulers
The scheduler component’s main task is to – surprise – schedule work in the form of
tasks on a physical processor(s). When a task requests processor time, it is the scheduler
that assigns worker threads to the task, so the request is processed. The scheduler is also
responsible for making sure worker threads cooperate with each other and yield the
processor when their slice of time, or quantum, has expired. We call this cooperative, or
non-preemptive, scheduling. The need for worker threads to yield when their processor
time has expired comes from the fact that a scheduler allows only one worker thread to
run on a processor at a time. If the worker threads didn’t need to yield, a worker thread
might stay on the processor for an infinite amount of time, blocking all usage of that
processor.
There is a one-on-one relation between processors and schedulers. If your system
has two processors, each with four cores, there will be eight schedulers that the SQLOS
can use to process user requests, each of them mapped to one of the logical processors.
We can access information about the schedulers by running a query against the
sys.dm_os_schedulers DMV:

SELECT *
FROM sys.dm_os_schedulers;

The results of the query are shown in Figure 1-11.

17
Chapter 1 Wait Statistics Internals

Figure 1-11. sys.dm_os_schedulers query results

The SQL Server on which I ran this query has two processors with two cores, which
means there should be four schedulers to process user requests. If we look at Figure 1-11,
however, we notice there are more than four schedulers returned by the query. SQL
Server uses its own schedulers to perform internal tasks, and those schedulers are
returned by the DMV and marked “HIDDEN ONLINE” in the status column. The
schedulers available for user requests are marked as “VISIBLE ONLINE.” There is also a
special type of scheduler with the status “VISIBLE ONLINE (DAC).” This is a scheduler
dedicated for use with the Dedicated Administrator Connection (DAC). This scheduler
makes it possible to connect to SQL Server in situations where it is unresponsive, for
instance, when there are no free worker threads available on the schedulers processing
user requests.
We view the number of worker threads a scheduler has associated with it by looking
at the current_workers_count column. This number also includes worker threads not
performing any work. The active_workers_count shows us the worker threads that are
active on the specific scheduler. This doesn’t mean they are running on the processor, as
worker threads with states of “RUNNING,” “RUNNABLE,” and “SUSPENDED” also count
toward this number. The work_queue_count is also an interesting column as it provides
insight into how many tasks are waiting for a free worker thread. If you see high numbers
in this column, it might mean you are experiencing CPU pressure.

18
Chapter 1 Wait Statistics Internals

Putting It All Together


All SQL Server scheduling parts discussed above are connected to each other, as every
connection, session, and query request passes through these same components. The
following text is an example of how a query request would get processed:

A user connects to the SQL Server through an application.

SQL Server creates a session after the login process is completed


successfully.

When the user sends a query to the SQL Server, a task and a
request are created to represent the unit of work that needs to
be done.

The scheduler will assign worker threads to the task so it can be


completed.

To see this information in SQL Server, we join some of the DMVs discussed. The
query in Listing 1-1 will show you an example of how to combine different DMVs to get
scheduling information about a specific session (in this case a session with an ID of 55).

Listing 1-1. Join the different DMVs together to query scheduling information

SELECT
  r.session_id AS 'Session ID',
  r.command AS 'Type of Request',
  qt.[text] AS 'Query Text',
  t.task_address AS 'Task Address',
  t.task_state AS 'Task State',
  w.worker_address AS 'Worker Address',
  w.[state] AS 'Worker State',
  s.scheduler_address AS 'Scheduler Address',
  s.[status] AS 'Scheduler State'
FROM sys.dm_exec_requests r

19
Chapter 1 Wait Statistics Internals

CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) qt


INNER JOIN sys.dm_os_tasks t
      ON r.task_address = t.task_address
INNER JOIN sys.dm_os_workers w
      ON t.worker_address = w.worker_address
INNER JOIN sys.dm_os_schedulers s
      ON w.scheduler_address = s.scheduler_address
WHERE r.session_id = 70;

Figure 1-12 shows the information that the query returned on my test SQL Server.
To keep the results readable, I only selected columns from the DMVs to show the relation
between them.

Figure 1-12. Results of the query from Listing 1-1

In the results, we see Session ID 70 made a SELECT query request. In the query
from Listing 1-1, we obtain the text of the query request using a cross apply with the sys.
dm_exec_sql_text Dynamic Management Function. The request was then mapped to a
task, and the task began running. The task was then mapped to a worker thread, and the
task was now in a running state. This meant the query began processing on a processor.
The Scheduler Address column shows on which specific scheduler our worker thread
was run.

Wait Statistics
So far, we have gone deep into the different components which perform scheduling for
SQL Server and how they are interconnected. Now we turn our attention to the main
topic of this book: wait statistics.
In the section on worker threads earlier in this chapter, I described the states a
worker thread is in while performing work on a scheduler. When a worker thread is
performing its work, it goes through three different phases (or queues) in the scheduler
process. Depending on the phase (or queue) a worker thread is in, it will enter the
“RUNNING,” “RUNNABLE,” or “SUSPENDED” state. Figure 1-13 shows an abstract view
of a scheduler with the different phases.

20
Chapter 1 Wait Statistics Internals

Figure 1-13. Scheduler and its phases and queues

When a worker thread obtains access to a scheduler, it will generally start in the
Waiter List and be assigned the “SUSPENDED” state. The Waiter List (shown as Waiting
in Figure 1-13) is an unordered list of worker threads with the “SUSPENDED” state and
is waiting for resources to become available. Here, resources are anything on the system,
such as data pages or maybe a lock request. While a worker thread is in the Waiter List,
the SQLOS records the type of resource it needs to continue its work (this is the wait
type) and the time it spends waiting before that specific resource becomes available (this
is the resource wait time).
When a worker thread receives access to the resources it needs, it will move to
the Runnable Queue, a first-in-first-out list of all worker threads with access to their
resources and ready to be run on a processor. The time a worker thread spends in the
Runnable Queue is recorded as the signal wait time.
The top worker thread in the Runnable Queue will move to the “RUNNING” phase,
where it will receive processor time to perform its work. The time it spends on the
processor is recorded as CPU time. In the meantime, the other worker threads in the
Runnable Queue move up the list, and worker threads that have received their requested
resources move from the Waiter List into the Runnable Queue.

21
Chapter 1 Wait Statistics Internals

Nerd Note The Runnable Queue is a first-in-first-out list (FIFO). If this was not
true, a task could theoretically never move from runnable to running on a busy
system. The Waiter List, however, is not FIFO.

While a worker thread is in the “RUNNING” phase, there are three scenarios that
can happen:

1. The worker thread needs additional resources; in this case, it


moves from the “RUNNING” phase to the Waiter List (what we see
as SUSPENDED).

2. The worker thread spends its quantum (fixed value of 4


milliseconds) and therefore must yield; the worker thread is
moved to the bottom of the Runnable Queue.

3. The worker thread is done with its work and will leave the
scheduler.

Worker threads move through the three different phases all the time. It is common
for one worker thread to rotate through multiple times until all work is done.
Knowing the different lengths of time a request spends in one of the three different
phases makes it possible to calculate total request execution time and also the total time
a request waits for either processor time or resource time.
Expressed as a mathematical formula, the total request execution time would look
like this:

TotalRequestExecutionTime = Running time + Runnable time + Suspended time

This can also be written as the following:

TotalRequestExecutionTime = CPU time + Signal wait time + Resource wait time

Since there is a lot of terminology involved in the scheduling of worker threads in


SQL Server, let’s show an example on how worker threads move through a scheduler.
Figure 1-14 shows you an abstract image of the Waiter Queue, the Runnable Queue,
and a processor executing a request.

22
Chapter 1 Wait Statistics Internals

Figure 1-14. Scheduler with requests

In this example, we see a request from SPID 77 running on the processor; this
request will have the state “RUNNING.” There are requests in the Waiter Queue waiting
for resources. I won’t go into detail about the wait types listed since we will be covering
wait types in Part II of this book. While these sessions are in the Waiter Queue SQL
Server will record the time spent as wait time, and the wait type will be noted as the
representation of the resource they are waiting for. If we query information about
these threads, they will have the “SUSPENDED” state. SPID 81 and SPID 91 have their
resources ready and are waiting in the Runnable Queue for SPID 77 to complete its work
on the processor. While they are waiting in the Runnable Queue, SQL Server records the
time they spend there as signal wait time and adds this time to the total wait time. These
worker threads will have the status of “RUNNABLE.”
In Figure 1-15 we have moved a few milliseconds forward in time; notice how the
scheduler and worker threads have moved through the different phases and queues.

23
Chapter 1 Wait Statistics Internals

Figure 1-15. Scheduler with requests after a few milliseconds

SPID 67 is done waiting for the PAGEIOLATCH_SH wait type and has moved to the
bottom of the Runnable Queue. Figure 1-16 shows the next few milliseconds in time.

Figure 1-16. A few milliseconds more

SPID 77 needs an additional resource and has been placed back into the waiting
queue. Here I have chosen to place it in the middle of the image to better represent that
the Waiter Queue is not a FIFO queue. Figure 1-17 shows the next few milliseconds.

24
Chapter 1 Wait Statistics Internals

Figure 1-17. A few milliseconds more

SPID 81 was the first worker thread in the Runnable Queue, and now with the
processor free it moves from the Runnable Queue to the processor, and the state changes
from “RUNNABLE” to “RUNNING.”
And that is how worker threads move from “SUSPENDED” to “RUNNABLE” to
“RUNNING” until the request(s) are complete and they exit the scheduler.

Summary
In this chapter, we reviewed the history of wait statistics throughout various versions of
SQL Server. With the introduction of the SQLOS in SQL Server 2005, a lot changed in how
SQL Server processed requests, introducing schedulers, worker threads, and tasks. All
the information for the various parts are stored in Dynamic Management Views (DMVs)
or Dynamic Management Functions (DMFs), which are easily queried and return a lot of
information about the internals of SQL Server.
Using these DMVs, we view the progress of requests while they are handled by a SQL
Server scheduler and learn if they are waiting for any specific resources. The resources
the requests are waiting for and the time they spend waiting for those resources are
recorded as wait statistics, the main topic of this book.

25
CHAPTER 2

Querying SQL Server Wait


Statistics
With the introduction of Dynamic Management Views (DMVs) and Dynamic
Management Functions (DMFs) in SQL Server 2005, viewing and analyzing wait statistics
became easier and less tedious. In SQL Server versions prior to SQL Server 2005, users
were limited to the DBCC SQLPERF('WAITSSTATS') command to view wait statistics.
Presently, there are a variety of DMVs which return wait statistics related information,
and in this chapter, we will take a detailed look at four of the most useful DMVs: sys.
dm_os_wait_stats, sys.dm_os_waiting_tasks, sys.dm_exec_requests, and sys.dm_
exec_session_wait_stats.
Viewing wait statistics information is not only limited to DMVs though. We can also
use the Performance Monitor, or Perfmon, to view wait statistics information.
SQL Server 2008 introduced yet another option to view wait statistics, Extended
Events. Extended Events were difficult to work with in SQL Server 2008, (you had to write
the entire Extended Event session in T-SQL), but Microsoft has drastically improved
Extended Events in later versions making them more user-friendly and easier to use.
SQL Server 2016 SP1 introduced two new methods to access wait statistics: through
a new DMV called sys.dm_exec_session_wait_stats and by adding wait statistics
information on a per-query basis inside execution plans.
In SQL Server 2017, Microsoft took recording wait statistics another step forward
by including them inside the Query Store. The Query Store is a feature introduced in
SQL Server 2016 and acts like a flight recorder for your query workload, logging query
statement, performance, and resource utilization.
In this chapter, we will look at the sources which capture wait statistics mentioned
in the previous paragraphs, starting with the DMVs. Because the Query Store feature has
such a big impact on troubleshooting and analyzing query performance, including wait
statistics, we will take a thorough look at it in Chapter 3, “The Query Store.”

27
© Thomas LaRock, Enrico van de Laar 2023
T. LaRock and E. van de Laar, Pro SQL Server 2022 Wait Statistics,
https://doi.org/10.1007/978-1-4842-8771-2_2
Chapter 2 Querying SQL Server Wait Statistics

sys.dm_os_wait_stats
The sys.dm_os_wait_stats DMV is one of the most important DMVs regarding wait
statistics. This DMV is the replacement for the DBCC SQLPERF('WAITSTATS')
command in use before SQL Server 2005. All the information returned from the DBCC
SQLPERF('WAITSTATS') command is included in the sys.dm_os_wait_stats DMV, plus a
little bit more.
The sys.dm_os_wait_stats DMV shows the total amount of wait time for every wait
type since the SQL Server instance was started. It is cumulative, adding wait time to the
different wait types, resulting in an ever-increasing total. Querying the sys.dm_os_wait_
stats DMV provides insight into what the query requests were waiting for. This is helpful
if you are looking for the grand total of wait time for every wait type, but many times you
are interested in the wait time for a specific time segment, or query. In this case, it is
possible to reset the sys.dm_os_wait_stats DMV without having to restart SQL Server by
using the following command:

DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);

This will reset wait statistics information back to 0 again, meaning you lose all
information before the reset. In Chapter 4, “Building a Solid Baseline,” we will examine a
method which will not completely reset the sys.dm_os_wait_stats counters.
As with every DMV in SQL Server, we execute a query against the sys.dm_os_wait_
stats DMV as if it were a table, in this case:

SELECT *
FROM sys.dm_os_wait_stats;

The results of this query are shown in Figure 2-1.

28
Random documents with unrelated
content Scribd suggests to you:
the famous oratorio, Moses in Egypt, which has also been performed
as an opera; and in 1842 his Stabat Mater was produced. He died
13th November, 1868.

STRAUSS
Richard Strauss was born 11th June, 1864, at Munich. He showed
great musical talent from the earliest years, having composed
several pieces before leaving school. In 1882, he studied
composition with the Court Kapellmeister, composing almost
ceaselessly string quartettes, symphonies and overtures, most of
which were performed and received as promising productions. He
was at the University during 1882-3, and in 1885 began to conduct,
being appointed musical director at Meiningen, proceeding to the
Munich Court Theatre in 1886. He was next appointed musical
director at Weimar in 1890, and became Court Kapellmeister at the
Berlin Opera House in the same year. He travelled in Italy during
1885. His first opera, Guntran, was produced at Weimar on 12th
May, 1894; and in the same year he became Count Kapellmeister at
Munich, again occupying the same position at Berlin in 1899. He
undertook a number of tours, and in 1897 visited London, where a
"Strauss Festival" was held in St. James's Hall, June, 1903. Strauss
continued to produce more and more important works, consisting of
symphonies, sonatas, tone-poems, and many songs, choral and
orchestral pieces, all of which proved his great gift for musical
composition and paved the way for the remarkable operatic works
which were to follow. He always had a great admiration for Wagner,
whose successor he wished to be regarded as; and in his next
opera, Fuersnot, produced at Dresden in November, 1901, this was
indicated very plainly. His remarkable opera, Salome, based on Oscar
Wilde's drama, was produced at Dresden, 9th December, 1905, and
created a great sensation, placing Strauss at once in the front rank
of operatic composers. This was followed by Elektra—by many
regarded as his finest work—produced at Dresden in 1909, and at
Covent Garden, London, in 1910, and Der Rosenkavalier, produced
at the Royal Opera House, Dresden, 26th January, 1911, and in
London, January, 1913—both of which have added to the now
world-wide reputation and appreciation of this highly-gifted
composer.
His latest work, Ariadne au Naxos—a clever "freak" opera written as
an incidental musical interlude to Molière's Le Bourgeois
Gentilhomme—was produced in London at His Majesty's Theatre, on
27th May, 1913, having been heard previously at Stuttgart in
October, 1912.

AMBROISE THOMAS
Charles Ambroise Thomas was born at Metz, 5th August, 1811; died at
Paris, 12th February, 1896. Born of musical parents, he entered the
Paris Conservatoire at the age of seventeen, becoming director of
that institute in 1871. In 1832 he won the Grand Prix de Rome; and
whilst studying in Italy was very active as a composer. On his return
from Rome he began to write operas, the first of which, La Double
Echelle, produced at the Opéra Comique in 1837, met with
considerable success. Others followed; and with Le Caid (1849) and
Le Songe d'une Nuit d'été (1850), his name was finally
established, and gained him a high place amongst French
composers. The operas that followed met with little success; but in
Mignon, produced at the Opéra Comique in 1866, the musical
world recognised a masterpiece, and paid enthusiastic tribute to the
genius of its composer. Other operas by Ambroise Thomas are:—
Hamlet (1868), Le Cardinal de Venise (1857), Raymond (1851), etc.

TSCHAIKOVSKY
Peter Iljtsch Tschaikovsky was born in Wotkinsk, 7th May, 1840; died
at St. Petersburg, 5th November, 1905. He early showed his bent for
music, and though trained for the law, abandoned that profession,
and, determining to study music alone, entered the Conservatoire at
St. Petersburg, where he studied with Anton Rubinstein and
Saremba. After studying three years in St. Petersburg, Tschaikovsky
was appointed a teacher at the new Moscow Conservetorium,
established by Nicholas Rubinstein, where he produced a number of
orchestral works and three operas. His first opera, The Voïevoda,
produced in Moscow in 1869, was a failure; and of the list of eleven
operas which he produced, but a few retained lasting popularity,
with the exception of Vakoula the Blacksmith, and Eugene Onegin.
The latter is the most famous of all his works, and is still extremely
popular in Russia, being full of delightful melodies. Eugene Onegin
was first produced in Moscow in 1879. Amongst his other operas are
The Enchantress, The Queen of Spades; Joan of Arc, Mazeppa,
Iolanthe, Undine, The Oprichinki. Besides these, Tschaikovsky wrote
a great number of brilliant orchestral works, deservedly popular
throughout Europe, being noted for their fine tone-colouring, spirit,
and beauty of melody: amongst the most celebrated of these being
the rich Overture "1812," composed in memory of Nicholas
Rubinstein, the Fifth Symphony and the Sixth Symphony, The
Pathètique.

VERDI
Giuseppe Verdi was born at Rancola, in the Duchy of Parma, Italy,
10th October, 1813; died at Busseto, in January, 1901. He received
his musical education at Busseto and Milan. He was appointed
organist at Rancola at the age of ten years; and when but twenty
years old he became Director of the Philharmonic Society at Busseto.
He settled in Milan in 1838, and there his first opera, Oberto di San
Bonifazio, was produced at La Scala in 1839. The opera that first
brought him European fame was Ernani (1844). Rigoletto was
produced in 1851, and Il Trovatore in 1853; and these two operas,
through all changes of taste and style, still continue to hold their
own in popular favour. He wrote many other operas, the best known
of which are: La Traviata (1853), Aïda (1871), Othello (1877),
Macbeth (1847), Falstaff (1893), I Lombardi (1843), Un Ballo in
Maschera (1859), Simon Boccanegra (1857), Les Vespres Siciliennes
(1855), etc. His other works include a Requiem Mass (1847), and
other sacred compositions, etc.

WAGNER
Richard Wagner was born at Leipzig on 22nd May, 1813; died at
Venice, 13th February, 1883. He was educated at Dresden and
Leipzig, where he also studied music. Poetry was a passion with him
as a boy; and verse and play-writing occupied his mind until a great
enthusiasm for Beethoven turned it into a musical direction. He was
Musical Director at the Magdeburg Theatre from 1834-36, Conductor
at Königsberg in 1836, Music Director at Riga in 1837-39, and lived
in Paris in 1839-42, where he struggled in vain to obtain a footing.
His opera Rienzi was produced at Dresden in 1842 with a success
which obtained for him the post of Kapellmeister at the opera-house
there. The Flying Dutchman was produced the following year at
Dresden, and marked a new epoch in his artistic history.
Tannhäuser, the first of his creations from the German myth-world,
was also produced at Dresden in 1845. After this he got into
pecuniary difficulties; and his sympathies also being with the
revolutionary movement of 1849, he was proscribed, and escaped to
Paris. By the efforts of Liszt, Lohengrin was produced in 1850 at
Weimar. After ten years of exile, Wagner was pardoned, and took up
his residence at Munich, where King Ludwig of Bavaria became his
enthusiastic and generous patron. Tristan and Isolda was produced
at Munich in 1865; and this genuine music-drama marked a new
epoch in operatic art. Die Meistersinger followed in 1868. Wagner
was now world-famous, and his colossal genius began to receive the
support it deserved. In 1872 his own great theatre at Bayreuth was
founded; and upon its completion in 1876, his noble tetralogy, Der
Ring des Nibelungen was produced there. His last dramatic effort
and crowning achievement, Parsifal, was produced at Bayreuth in
1882. Wagner's early years were full of struggle, opposition, and
strife; but through all his disappointments he clung firmly to the new
and great ideals of art he had formed, and in the end he conquered,
his latter years being crowned with success and enthusiastic
appreciation.

WALLACE
William Vincent Wallace was born at Waterford, Ireland, 1st July,
1814; died at the château of Bayen, in the Haute-Garonne, France,
12th October, 1865. His father, a bandmaster, gave him his first
instructions; and at an early age he could play most military
instruments, besides being very proficient on the violin. At the age of
fifteen he became Director of the Philharmonic Society in Dublin. In
1835 he set forth on a professional tour through Australia, New
Zealand, India, South America, and the United States, meeting with
enormous success as composer and performer. He was Director of
Music at the Italian Theatre, Mexico, 1841-42. In 1845 Maritana was
produced in London, and shares with Balfe's Bohemian Girl the
highest popularity of any lyrical drama. Other well-known operas of
Wallace's are: Lurline (1860), The Amber Witch (1861), Matilda of
Hungary (1847), The Desert Flower (1863), etc.

VON WALTERSHAUSEN
Hermann Wolfgang von Waltershausen was born in Göttingen in 1882,
and was the son of a Strasburg Professor of National Economics, A.
Sartorius von Waltershausen, being descended from a well-known
Göttingen family of scientists. He was the pupil of I. Erb, in
Strasburg, Elsass, and Ludwig Thuille, afterwards passing to the
University of Munich, where he studied in particular the History of
Art and also made a special study of the characteristics of the
German peoples. His first musical work was the unpublished music-
drama, Pelegrino, and his second effort was Else Klapperzehen, a
musical comedy dealing with a farcical subject taken from the
German Middle Ages, and which was produced in May, 1909, by
Ernst von Schuch at the Court Theatre, Munich, with success. His
third work, the musical tragedy, Oberst Chabert, was given under
the conductorship of Hans Schilling-Ziemssens Leitung, 18th
January, 1912, and, being immediately successful, found its way very
quickly into all the more important theatres. In addition to these
works, Herr von Waltershausen has also written purely literary
works, amongst others the Festival Play, Die Abschiedssyphonie,
produced in Munich in 1908, the comedy in verse, Heidhart Fuchs
von Reuenthal, as well as portions of a translation of Horace in very
modern form. Herr von Waltershausen resides in Munich.

WOLF-FERRARI
Ermanni Wolf-Ferrari was born 12th January, 1876, at Venice. He
studied under Rheinberge at Munich from 1893 to 1895; and in 1902
he was appointed Director of the Liceo Benedetto Marcello in Venice,
from which position he resigned in 1909, as he desired to live in
Germany. He produced his first opera, La Sulamita, at Venice in 1889
before he went to Munich, this work being the result of his own self-
teaching. Other operas followed: Cenerentola, produced at Venice in
1902; Le Donne Curiose, in 1903, this latter opera having been
recently produced with success in America. His fine cantata, La Vita
Nuova, dealing with the subject of Dante and Beatrice, was brought
out in 1903. A light opera, The Secret of Susanna, followed this, and
was produced in England in 1911; and his dramatic opera, The
Jewels of the Madonna, was given in England during the summer of
1912.
ALPHABETICAL LIST OF OPERAS

OPERA COMPOSER PAGE


Aïda Verdi 377
Barber of Seville, The
(Il Barbiere di
Rossini 282
Seviglia)
Bohème, La Puccini 255
Bohemian Girl, The Balfe 14
Carmen Bizet 62
Cavalleria Rusticana
(Rustic Chivalry) Mascagni 165
Chabert, Colonel
(Oberst Chabert) Waltershausen 513
Daughter of the
Regiment, The
(La Figlia del Donizetti 87
Reggimento)
Don Juan (Don
Mozart 217
Giovanni)
Elektra Strauss 301
Ernani Verdi 328
Eugene Onegin Tschaikovsky 318
Faust Gounod 105
Fidelio Beethoven 28
Figaro, The Marriage
of
(Le Nozze di Mozart 206
Figaro)
Flying Dutchman,
The
(Der Fliegende Wagner 397
Holländer)
Fra Diavolo Auber 1
Huguenots, The
(Les Huguenots) Meyerbeer 180
Jewels of the
Madonna, The
(I Gioielli della Wolf-Ferrari 524
Madonna)
Jewess, The
(La Juive) Halèvy 135
Königskinder, Die
(The Kingly
Humperdinck 143
Children)
Lily of Killarney, The Benedict 52
Lohengrin Wagner 418
Lucia di Lammermoor Donizetti 80
Lucrezia Borgia Donizetti 73
Lurline Wallace 508
Madam Butterfly Puccini 270
Manon Lescaut Puccini 247
Maritana Wallace 495
Martha Flotow 95
Masked Ball, The
(Un Ballo in
Verdi 370
Maschera)
Mastersingers of
Nuremberg, The
(Die Meistersinger Wagner 438
von Nürnberg)
Merry Wives of
Nicolai 229
Windsor, The
Mignon Thomas 307
Othello Verdi 390
Pagliacci,
(The Mountebanks) Leoncavallo 158
Parsifal Wagner 480
Philemon and Baucis Gounod 115
Puritani, I Bellini 46
Robert the Devil
(Robert le Diable) Meyerbeer 171
Romeo and Juliet Gounod 125
Rosenkavalier, Der
(The Rose-Bearer) Strauss 289
Rhinegold, The
(Das Rheingold)—
Part I. of
"The Nibelungs'
Ring"
Wagner 449
(Der Ring der
Nibelungen)
Rigoletto Verdi 337
Siegfried—Part III. of
"The Nibelungs'
Ring"
(Der Ring der
Wagner 464
Nibelungen)
Sonnambula, La Bellini 38
Star of the North,
The Meyerbeer 192
(L'Etoile du Nord)
Tales of Hoffmann,
The
(Les Contes Offenbach 238
d'Hoffmann)
Tannhäuser Wagner 406
Traviata, La Verdi 361
Tristan and Isolda Wagner 429
Trovatore, Il, or, The
Gipsy's Vengeance
Verdi 348
(The Troubadour)
Twilight of the Gods,
The
(Die
Götterdämmerung)
—Part IV. of
"The Nibelungs'
Wagner 472
Ring"
(Der Ring der
Nibelungen)
Valkyrie, The
(Die Walküre)—
Part II. of
"The Nibelungs'
Ring"
Wagner 455
(Der Ring der
Nibelungen)
PRINTED IN GREAT BRITAIN BY
THE NORTHUMBERLAND PRESS LIMITED, NEWCASTLE-UPON-TYNE
TRANSCRIBER'S NOTES:
A number of words in this book have both
hyphenated and non-hyphenated variants. For the
words with both variants present the one more used
has been kept.
Obvious punctuation and other printing errors have
been corrected.
The Italian title of Verdi's opera "The Masked Ball"
has been changed to "Un Ballo in Maschera", which
is the correct Italian title of the opera.
The correct name of one of the characters of
Donizetti's opera "Lucrezia Borgia" is Gennaro and
not Genarro as was printed in the book. It has been
changed. The modification makes the spelling
consistent with the one from the opera "The Jewels
of the Madonna," which is also described in the
book.
The book cover was modified by the Transcriber and
has been added to the public domain.
*** END OF THE PROJECT GUTENBERG EBOOK STORIES FROM
THE OPERAS ***

Updated editions will replace the previous one—the old editions


will be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States
copyright in these works, so the Foundation (and you!) can copy
and distribute it in the United States without permission and
without paying copyright royalties. Special rules, set forth in the
General Terms of Use part of this license, apply to copying and
distributing Project Gutenberg™ electronic works to protect the
PROJECT GUTENBERG™ concept and trademark. Project
Gutenberg is a registered trademark, and may not be used if
you charge for an eBook, except by following the terms of the
trademark license, including paying royalties for use of the
Project Gutenberg trademark. If you do not charge anything for
copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such
as creation of derivative works, reports, performances and
research. Project Gutenberg eBooks may be modified and
printed and given away—you may do practically ANYTHING in
the United States with eBooks not protected by U.S. copyright
law. Redistribution is subject to the trademark license, especially
commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the


free distribution of electronic works, by using or distributing this
work (or any other work associated in any way with the phrase
“Project Gutenberg”), you agree to comply with all the terms of
the Full Project Gutenberg™ License available with this file or
online at www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand,
agree to and accept all the terms of this license and intellectual
property (trademark/copyright) agreement. If you do not agree
to abide by all the terms of this agreement, you must cease
using and return or destroy all copies of Project Gutenberg™
electronic works in your possession. If you paid a fee for
obtaining a copy of or access to a Project Gutenberg™
electronic work and you do not agree to be bound by the terms
of this agreement, you may obtain a refund from the person or
entity to whom you paid the fee as set forth in paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only


be used on or associated in any way with an electronic work by
people who agree to be bound by the terms of this agreement.
There are a few things that you can do with most Project
Gutenberg™ electronic works even without complying with the
full terms of this agreement. See paragraph 1.C below. There
are a lot of things you can do with Project Gutenberg™
electronic works if you follow the terms of this agreement and
help preserve free future access to Project Gutenberg™
electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright
law in the United States and you are located in the United
States, we do not claim a right to prevent you from copying,
distributing, performing, displaying or creating derivative works
based on the work as long as all references to Project
Gutenberg are removed. Of course, we hope that you will
support the Project Gutenberg™ mission of promoting free
access to electronic works by freely sharing Project Gutenberg™
works in compliance with the terms of this agreement for
keeping the Project Gutenberg™ name associated with the
work. You can easily comply with the terms of this agreement
by keeping this work in the same format with its attached full
Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.

1.E. Unless you have removed all references to Project


Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project
Gutenberg™ work (any work on which the phrase “Project
Gutenberg” appears, or with which the phrase “Project
Gutenberg” is associated) is accessed, displayed, performed,
viewed, copied or distributed:

This eBook is for the use of anyone anywhere in the United


States and most other parts of the world at no cost and
with almost no restrictions whatsoever. You may copy it,
give it away or re-use it under the terms of the Project
Gutenberg License included with this eBook or online at
www.gutenberg.org. If you are not located in the United
States, you will have to check the laws of the country
where you are located before using this eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is


derived from texts not protected by U.S. copyright law (does not
contain a notice indicating that it is posted with permission of
the copyright holder), the work can be copied and distributed to
anyone in the United States without paying any fees or charges.
If you are redistributing or providing access to a work with the
phrase “Project Gutenberg” associated with or appearing on the
work, you must comply either with the requirements of
paragraphs 1.E.1 through 1.E.7 or obtain permission for the use
of the work and the Project Gutenberg™ trademark as set forth
in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is


posted with the permission of the copyright holder, your use and
distribution must comply with both paragraphs 1.E.1 through
1.E.7 and any additional terms imposed by the copyright holder.
Additional terms will be linked to the Project Gutenberg™
License for all works posted with the permission of the copyright
holder found at the beginning of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files
containing a part of this work or any other work associated with
Project Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute


this electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the
Project Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™
works unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or


providing access to or distributing Project Gutenberg™
electronic works provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project


Gutenberg™ electronic work or group of works on different
terms than are set forth in this agreement, you must obtain
permission in writing from the Project Gutenberg Literary
Archive Foundation, the manager of the Project Gutenberg™
trademark. Contact the Foundation as set forth in Section 3
below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on,
transcribe and proofread works not protected by U.S. copyright
law in creating the Project Gutenberg™ collection. Despite these
efforts, Project Gutenberg™ electronic works, and the medium
on which they may be stored, may contain “Defects,” such as,
but not limited to, incomplete, inaccurate or corrupt data,
transcription errors, a copyright or other intellectual property
infringement, a defective or damaged disk or other medium, a
computer virus, or computer codes that damage or cannot be
read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except


for the “Right of Replacement or Refund” described in
paragraph 1.F.3, the Project Gutenberg Literary Archive
Foundation, the owner of the Project Gutenberg™ trademark,
and any other party distributing a Project Gutenberg™ electronic
work under this agreement, disclaim all liability to you for
damages, costs and expenses, including legal fees. YOU AGREE
THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT
LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT
EXCEPT THOSE PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE
THAT THE FOUNDATION, THE TRADEMARK OWNER, AND ANY
DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE
TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL,
PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE
NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of
receiving it, you can receive a refund of the money (if any) you
paid for it by sending a written explanation to the person you
received the work from. If you received the work on a physical
medium, you must return the medium with your written
explanation. The person or entity that provided you with the
defective work may elect to provide a replacement copy in lieu
of a refund. If you received the work electronically, the person
or entity providing it to you may choose to give you a second
opportunity to receive the work electronically in lieu of a refund.
If the second copy is also defective, you may demand a refund
in writing without further opportunities to fix the problem.

1.F.4. Except for the limited right of replacement or refund set


forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’,
WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of
damages. If any disclaimer or limitation set forth in this
agreement violates the law of the state applicable to this
agreement, the agreement shall be interpreted to make the
maximum disclaimer or limitation permitted by the applicable
state law. The invalidity or unenforceability of any provision of
this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the


Foundation, the trademark owner, any agent or employee of the
Foundation, anyone providing copies of Project Gutenberg™
electronic works in accordance with this agreement, and any
volunteers associated with the production, promotion and
distribution of Project Gutenberg™ electronic works, harmless
from all liability, costs and expenses, including legal fees, that
arise directly or indirectly from any of the following which you
do or cause to occur: (a) distribution of this or any Project
Gutenberg™ work, (b) alteration, modification, or additions or
deletions to any Project Gutenberg™ work, and (c) any Defect
you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new
computers. It exists because of the efforts of hundreds of
volunteers and donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project
Gutenberg™’s goals and ensuring that the Project Gutenberg™
collection will remain freely available for generations to come. In
2001, the Project Gutenberg Literary Archive Foundation was
created to provide a secure and permanent future for Project
Gutenberg™ and future generations. To learn more about the
Project Gutenberg Literary Archive Foundation and how your
efforts and donations can help, see Sections 3 and 4 and the
Foundation information page at www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-
profit 501(c)(3) educational corporation organized under the
laws of the state of Mississippi and granted tax exempt status
by the Internal Revenue Service. The Foundation’s EIN or
federal tax identification number is 64-6221541. Contributions
to the Project Gutenberg Literary Archive Foundation are tax
deductible to the full extent permitted by U.S. federal laws and
your state’s laws.

The Foundation’s business office is located at 809 North 1500


West, Salt Lake City, UT 84116, (801) 596-1887. Email contact
links and up to date contact information can be found at the
Foundation’s website and official page at
www.gutenberg.org/contact
Section 4. Information about Donations to
the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission
of increasing the number of public domain and licensed works
that can be freely distributed in machine-readable form
accessible by the widest array of equipment including outdated
equipment. Many small donations ($1 to $5,000) are particularly
important to maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws


regulating charities and charitable donations in all 50 states of
the United States. Compliance requirements are not uniform
and it takes a considerable effort, much paperwork and many
fees to meet and keep up with these requirements. We do not
solicit donations in locations where we have not received written
confirmation of compliance. To SEND DONATIONS or determine
the status of compliance for any particular state visit
www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states


where we have not met the solicitation requirements, we know
of no prohibition against accepting unsolicited donations from
donors in such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot


make any statements concerning tax treatment of donations
received from outside the United States. U.S. laws alone swamp
our small staff.

Please check the Project Gutenberg web pages for current


donation methods and addresses. Donations are accepted in a
number of other ways including checks, online payments and
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebooknice.com

You might also like