Foreword |
|
xv | |
Introduction |
|
xvii | |
|
Chapter 1 Logical query processing |
|
|
1 | (40) |
|
Logical query-processing phases |
|
|
3 | (3) |
|
Logical query-processing phases in brief |
|
|
4 | (2) |
|
Sample query based on customers/orders scenario |
|
|
6 | (2) |
|
Logical query-processing phase details |
|
|
8 | (18) |
|
|
8 | (6) |
|
|
14 | (1) |
|
Step 3 The GROUP BY phase |
|
|
15 | (1) |
|
|
16 | (1) |
|
|
17 | (3) |
|
Step 6 The ORDER BY phase |
|
|
20 | (2) |
|
Step 7 Apply the TOP or OFFSET-FETCH filter |
|
|
22 | (4) |
|
Further aspects of logical query processing |
|
|
26 | (13) |
|
|
26 | (9) |
|
|
35 | (3) |
|
The UNION, EXCEPT, and INTERSECT operators |
|
|
38 | (1) |
|
|
39 | (2) |
|
|
41 | (146) |
|
|
41 | (12) |
|
|
42 | (1) |
|
|
43 | (10) |
|
Tools to measure query performance |
|
|
53 | (4) |
|
|
57 | (40) |
|
Table scan/unordered clustered index scan |
|
|
57 | (3) |
|
Unordered covering nonclustered index scan |
|
|
60 | (2) |
|
Ordered clustered index scan |
|
|
62 | (1) |
|
Ordered covering nonclustered index scan |
|
|
63 | (2) |
|
The storage engine's treatment of scans |
|
|
65 | (16) |
|
Nonclustered index seek + range scan + lookups |
|
|
81 | (10) |
|
Unordered nonclustered index scan + lookups |
|
|
91 | (2) |
|
Clustered index seek + range scan |
|
|
93 | (1) |
|
Covering nonclustered index seek + range scan |
|
|
94 | (3) |
|
|
97 | (18) |
|
Legacy estimator vs. 2014 cardinality estimator |
|
|
98 | (1) |
|
Implications of underestimations and overestimations |
|
|
99 | (2) |
|
|
101 | (3) |
|
Estimates for multiple predicates |
|
|
104 | (3) |
|
|
107 | (3) |
|
|
110 | (5) |
|
|
115 | (16) |
|
|
115 | (4) |
|
|
119 | (1) |
|
Filtered indexes and statistics |
|
|
120 | (3) |
|
|
123 | (7) |
|
|
130 | (1) |
|
Prioritizing queries for tuning with extended events |
|
|
131 | (3) |
|
Index and query information and statistics |
|
|
134 | (5) |
|
|
139 | (10) |
|
Set-based vs. iterative solutions |
|
|
149 | (4) |
|
Query tuning with query revisions |
|
|
153 | (5) |
|
|
158 | (28) |
|
How intraquery parallelism works |
|
|
158 | (17) |
|
Parallelism and query optimization |
|
|
175 | (6) |
|
The parallel APPLY query pattern |
|
|
181 | (5) |
|
|
186 | (1) |
|
Chapter 3 Multi-table queries |
|
|
187 | (72) |
|
|
187 | (17) |
|
Self-contained subqueries |
|
|
187 | (2) |
|
|
189 | (5) |
|
|
194 | (7) |
|
|
201 | (3) |
|
|
204 | (14) |
|
|
205 | (2) |
|
|
207 | (4) |
|
|
211 | (4) |
|
Inline table-valued functions |
|
|
215 | (1) |
|
|
215 | (3) |
|
|
218 | (6) |
|
|
219 | (2) |
|
|
221 | (1) |
|
|
221 | (1) |
|
|
222 | (2) |
|
|
224 | (25) |
|
|
224 | (4) |
|
|
228 | (1) |
|
|
229 | (1) |
|
|
230 | (1) |
|
|
230 | (1) |
|
|
231 | (6) |
|
|
237 | (2) |
|
|
239 | (6) |
|
|
245 | (4) |
|
The UNION, EXCEPT, and INTERSECT operators |
|
|
249 | (8) |
|
The UNION ALL and UNION operators |
|
|
250 | (3) |
|
|
253 | (2) |
|
|
255 | (2) |
|
|
257 | (2) |
|
Chapter 4 Grouping, pivoting, and windowing |
|
|
259 | (82) |
|
|
259 | (40) |
|
Aggregate window functions |
|
|
260 | (21) |
|
|
281 | (4) |
|
|
285 | (3) |
|
Statistical window functions |
|
|
288 | (3) |
|
|
291 | (8) |
|
|
299 | (8) |
|
|
300 | (4) |
|
|
304 | (3) |
|
|
307 | (6) |
|
Unpivoting with CROSS JOIN and VALUES |
|
|
308 | (2) |
|
Unpivoting with CROSS APPLY and VALUES |
|
|
310 | (2) |
|
Using the UNPIVOT operator |
|
|
312 | (1) |
|
|
313 | (14) |
|
|
314 | (1) |
|
|
315 | (1) |
|
|
316 | (11) |
|
|
327 | (12) |
|
|
328 | (3) |
|
|
331 | (2) |
|
|
333 | (1) |
|
Materializing grouping sets |
|
|
334 | (3) |
|
|
337 | (2) |
|
|
339 | (2) |
|
Chapter 5 TOP and OFFSET-FETCH |
|
|
341 | (32) |
|
The TOP and OFFSET-FETCH filters |
|
|
341 | (5) |
|
|
341 | (4) |
|
|
345 | (1) |
|
Optimization of filters demonstrated through paging |
|
|
346 | (14) |
|
|
346 | (8) |
|
Optimization of OFFSET-FETCH |
|
|
354 | (4) |
|
Optimization of ROW_NUMBER |
|
|
358 | (2) |
|
Using the TOP option with modifications |
|
|
360 | (3) |
|
|
360 | (1) |
|
|
361 | (2) |
|
|
363 | (5) |
|
Solution using ROW_NUMBER |
|
|
364 | (1) |
|
Solution using TOP and APPLY |
|
|
365 | (1) |
|
Solution using concatenation (a carry-along sort) |
|
|
366 | (2) |
|
|
368 | (3) |
|
Solution using PERCENTILE_CONT |
|
|
369 | (1) |
|
Solution using ROW_NUMBER |
|
|
369 | (1) |
|
Solution using OFFSET-FETCH and APPLY |
|
|
370 | (1) |
|
|
371 | (2) |
|
Chapter 6 Data modification |
|
|
373 | (46) |
|
|
373 | (8) |
|
|
373 | (3) |
|
|
376 | (1) |
|
Measuring the amount of logging |
|
|
377 | (1) |
|
|
378 | (3) |
|
|
381 | (14) |
|
Characteristics and inflexibilities of the identity property |
|
|
381 | (1) |
|
|
382 | (5) |
|
Performance considerations |
|
|
387 | (7) |
|
Summarizing the comparison of identity with sequence |
|
|
394 | (1) |
|
|
395 | (6) |
|
|
395 | (4) |
|
|
399 | (2) |
|
|
401 | (3) |
|
Update using table expressions |
|
|
402 | (1) |
|
|
403 | (1) |
|
|
404 | (7) |
|
|
405 | (3) |
|
Preventing MERGE conflicts |
|
|
408 | (1) |
|
|
409 | (1) |
|
|
410 | (1) |
|
|
411 | (6) |
|
Example with INSERT and identity |
|
|
412 | (1) |
|
Example for archiving deleted data |
|
|
413 | (1) |
|
Example with the MERGE statement |
|
|
414 | (3) |
|
|
417 | (1) |
|
|
417 | (2) |
|
Chapter 7 Working with date and time |
|
|
419 | (54) |
|
|
419 | (3) |
|
|
422 | (12) |
|
Challenges working with date and time |
|
|
434 | (15) |
|
|
434 | (2) |
|
|
436 | (3) |
|
Handling date-only or time-only data with DATETIME and SMALLDATETIME |
|
|
439 | (1) |
|
First, last, previous, and next date calculations |
|
|
440 | (5) |
|
|
445 | (2) |
|
|
447 | (2) |
|
Querying date and time data |
|
|
449 | (22) |
|
|
449 | (1) |
|
|
450 | (21) |
|
|
471 | (2) |
|
Chapter 8 T-SQL for BI practitioners |
|
|
473 | (52) |
|
|
473 | (3) |
|
|
474 | (2) |
|
|
476 | (3) |
|
Frequencies without window functions |
|
|
476 | (1) |
|
Frequencies with window functions |
|
|
477 | (2) |
|
Descriptive statistics for continuous variables |
|
|
479 | (16) |
|
Centers of a distribution |
|
|
479 | (3) |
|
|
482 | (5) |
|
Higher population moments |
|
|
487 | (8) |
|
|
495 | (17) |
|
|
495 | (6) |
|
Contingency tables and chi-squared |
|
|
501 | (4) |
|
|
505 | (4) |
|
|
509 | (3) |
|
Moving averages and entropy |
|
|
512 | (10) |
|
|
512 | (6) |
|
|
518 | (4) |
|
|
522 | (3) |
|
Chapter 9 Programmable objects |
|
|
525 | (146) |
|
|
525 | (21) |
|
|
525 | (4) |
|
Using the sp_executesql procedure |
|
|
529 | (1) |
|
|
530 | (5) |
|
Dynamic search conditions |
|
|
535 | (7) |
|
|
542 | (4) |
|
|
546 | (7) |
|
|
546 | (4) |
|
|
550 | (3) |
|
|
553 | (22) |
|
Compilations, recompilations, and reuse of execution plans |
|
|
554 | (17) |
|
Table type and table-valued parameters |
|
|
571 | (2) |
|
|
573 | (2) |
|
|
575 | (10) |
|
|
575 | (6) |
|
Efficient trigger programming |
|
|
581 | (4) |
|
|
585 | (47) |
|
|
586 | (2) |
|
CLR scalar functions and creating your first assembly |
|
|
588 | (9) |
|
Streaming table-valued functions |
|
|
597 | (8) |
|
SQLCLR stored procedures and triggers |
|
|
605 | (12) |
|
SQLCLR user-defined types |
|
|
617 | (11) |
|
SQLCLR user-defined aggregates |
|
|
628 | (4) |
|
Transaction and concurrency |
|
|
632 | (30) |
|
|
633 | (3) |
|
|
636 | (5) |
|
|
641 | (2) |
|
|
643 | (2) |
|
|
645 | (12) |
|
|
657 | (5) |
|
|
662 | (8) |
|
|
662 | (4) |
|
|
666 | (3) |
|
|
669 | (1) |
|
|
670 | (1) |
|
Chapter 10 In-Memory OLTP |
|
|
671 | (36) |
|
|
671 | (4) |
|
|
672 | (1) |
|
|
673 | (1) |
|
Lock and latch-free architecture |
|
|
673 | (1) |
|
|
674 | (1) |
|
Creating memory-optimized tables |
|
|
675 | (1) |
|
Creating indexes in memory-optimized tables |
|
|
676 | (14) |
|
Clustered vs. nonclustered indexes |
|
|
677 | (1) |
|
|
677 | (3) |
|
|
680 | (10) |
|
|
690 | (13) |
|
|
690 | (9) |
|
Natively compiled procedures |
|
|
699 | (4) |
|
Surface-area restrictions |
|
|
703 | (2) |
|
|
703 | (1) |
|
|
704 | (1) |
|
|
705 | (2) |
|
Chapter 11 Graphs and recursive queries |
|
|
707 | (96) |
|
|
707 | (2) |
|
|
707 | (1) |
|
|
708 | (1) |
|
|
709 | (1) |
|
|
709 | (9) |
|
Employee organizational chart |
|
|
709 | (2) |
|
|
711 | (4) |
|
|
715 | (3) |
|
|
718 | (24) |
|
|
719 | (11) |
|
|
730 | (3) |
|
Subgraph/descendants with path enumeration |
|
|
733 | (3) |
|
|
736 | (4) |
|
|
740 | (2) |
|
|
742 | (12) |
|
|
743 | (6) |
|
|
749 | (5) |
|
Materialized path with the HIERARCHYID data type |
|
|
754 | (24) |
|
|
756 | (7) |
|
|
763 | (4) |
|
Further aspects of working with HIERARCHYID |
|
|
767 | (11) |
|
|
778 | (9) |
|
Assigning left and right values |
|
|
778 | (6) |
|
|
784 | (3) |
|
|
787 | (14) |
|
|
787 | (14) |
|
|
801 | (2) |
Index |
|
803 | |