Beginning Microsoft SQL Server 2008 ... - S3 Tech Training
Beginning Microsoft SQL Server 2008 ... - S3 Tech Training Beginning Microsoft SQL Server 2008 ... - S3 Tech Training
Chapter 9: SQL Server Storage and Index Structures Now, the question is how do we use this information once we have it? The answer is, of course, that it depends. Using the output from our fragmentation query, we have a decent idea of whether our database is full, fragmented, or somewhere in between (the latter is, most likely, what we want to see). If we’re running an OLAP system, then having full pages would be great — fragmentation would bring on depression. For an OLTP system, we would want much the opposite (although only to a point). So, how do we take care of the problem? To answer that, we need to look into the concept of index rebuilding and fillfactors. ALTER INDEX and FILLFACTOR 294 Stat What It Means Logical Scan Fragmentation Extent Scan Fragmentation The percentage of pages that are out of order as checked by scanning the leaf pages of an index. Only relevant to scans related to a clustered table. An out-oforder page is one for which the next page indicated in the index allocation map (IAM) is different from that pointed to by the next page pointer in the leaf page. This one is telling whether an extent is not physically located next to the extent that it should be logically located next to. This just means that the leaf pages of your index are not physically in order (though they still can be logically), and it shows what percentage of the extents this problem pertains to. As we saw earlier in the chapter, SQL Server gives us an option for controlling just how full our leaf level pages are and, if we choose, another option to deal with non-leaf level pages. Unfortunately, these are proactive options. They are applied once, and then you need to reapply them as necessary by rebuilding or reorganizing your indexes to reapply the options. To rebuild indexes, we can either drop them and create them again (if you do, using the DROP_EXISTING option usually is a good idea), or make use of the ALTER INDEX command with the REBUILD option. Keep in mind, however, what was said previously about rebuilding indexes — unless you have the ONLINE option available, rebuilding indexes takes the index (and possibly the entire table) totally offline until the rebuild is complete. In general, reorganizing is going to be a better option. A reorg affects only the leaf level of the index (where most of the issue is likely to be anyway) and keeps the index online while the reorg is taking place. Reorganizing your indexes restructures all the leaf level information in those indexes, and reestablishes a base percentage that your pages are full. If the index in question is a clustered index, then the physical data is also reorganized. Unfortunately, REORGANIZE does not allow for the change of several index settings, such as FILLFACTOR. If the index has not had a specific fillfactor specified, the pages will be reconstituted to be full, minus two records. Just as with the CREATE TABLE syntax, you can set the FILLFACTOR to be any value between 1 and 100 as long as you are doing a full rebuild (as opposed to just a reorg). This number will be the percent that your pages are full once the database reorganization is complete. Remember, though, that as your pages split, your data will still be distributed 50-50 between the two pages — you cannot control the fill percentage on an ongoing basis other than by regularly rebuilding the indexes.
We use a FILLFACTOR when we need to adjust the page densities. As already discussed, lower page densities (and therefore lower FILLFACTORs) are ideal for OLTP systems where there are a lot of insertions; this helps prevent page splits. Higher page densities are desirable with OLAP systems (fewer pages to read, but no real risk of page splitting due to few to no inserts). If we wanted to rebuild the index that serves as the primary key for the Sales.SalesOrderDetail table we were looking at earlier with a fill factor of 65, we would issue an ALTER INDEX command as follows: ALTER INDEX PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID ON Sales.SalesOrderDetail REBUILD WITH (FILLFACTOR = 100) This would be a good time to digress and revisit the idea of your object names. Notice how long this name is. The more characters, the more chance for typos. Balance that against the need for the name to be meaningful. For this particular query, my own naming conventions would probably have dropped the inclusion of the table name (when referring to an index, you usually already know what table you’re talking about) and eliminated the underscores to wind up with something like PKSalesOrderIDSalesOrderDetailID. The name implies the nature of the index (it’s supporting a primary key) and the columns involved. Be careful, however, with using the column name idea. On the rare occasion you wind up with several columns in your index, it can make for an unruly index name. We can then re-run the sys.dm_db_index_physical_stats to see the effect: database_id object_id index_id index_depth avg_fragmentation_in_percent page_count ----------- ----------- ----------- ----------- ---------------------------- ----------- 8 610101214 1 3 0.0810372771474878 1234 8 610101214 2 3 1.70731707317073 410 8 610101214 3 2 6.14035087719298 228 (3 row(s) affected) Chapter 9: SQL Server Storage and Index Structures The big one to notice here is the change in avg_fragmentation_in_percent. Assuming we’re looking for high page densities (higher read performance), then we want the number as low as possible. The number didn’t quite reach 0 percent because SQL Server has to deal with page and row sizing, but it gets as close as it can. Several things to note about ALTER TABLE REINDEX/REORG and FILLFACTOR: ❑ If a FILLFACTOR isn’t provided, then the ALTER TABLE will use whatever setting was used to build the index previously. If one has never been specified, then the FILLFACTOR will make the page full (which is too full for most situations). ❑ If a FILLFACTOR is provided, then that value becomes the default FILLFACTOR for that index. ❑ While a REORGANIZE is done live and a REBUILD can be (if you have the licensing required to enable that feature), I strongly recommend against it. It locks resources and can cause a host of problems. At the very least, look at doing it at non-peak hours. 295
- Page 281 and 282: Chapter 8: Being Normal: Normalizat
- Page 283 and 284: Chapter 8: Being Normal: Normalizat
- Page 285 and 286: Chapter 8: Being Normal: Normalizat
- Page 287 and 288: Chapter 8: Being Normal: Normalizat
- Page 289 and 290: Chapter 8: Being Normal: Normalizat
- Page 291 and 292: Chapter 8: Being Normal: Normalizat
- Page 293 and 294: Chapter 8: Being Normal: Normalizat
- Page 295 and 296: Chapter 8: Being Normal: Normalizat
- Page 297 and 298: Chapter 8: Being Normal: Normalizat
- Page 299 and 300: 9 SQL Ser ver Storage and Index Str
- Page 301 and 302: Page Splits When a page becomes ful
- Page 303 and 304: The point here is that what happens
- Page 305 and 306: Page Splits — A First Look All of
- Page 307 and 308: You may hear lots of bad things abo
- Page 309 and 310: Navigating the Tree Figure 9-4 As I
- Page 311 and 312: there was no link between the data.
- Page 313 and 314: Root Non-Leaf Level Leaf Level Figu
- Page 315 and 316: The CREATE INDEX Statement The CREA
- Page 317 and 318: FILLFACTOR When SQL Server first cr
- Page 319 and 320: works only if tempdb is on a separa
- Page 321 and 322: Secondary XML Indexes Chapter 9: SQ
- Page 323 and 324: occur, and that one or more non-lea
- Page 325 and 326: isn’t room on the page, SQL Serve
- Page 327 and 328: more administrator oriented and usu
- Page 329 and 330: The Database Engine Tuning Advisor
- Page 331: The output is far more self-describ
- Page 335: Chapter 9: SQL Server Storage and I
- Page 338 and 339: Chapter 10: Views The preceding syn
- Page 340 and 341: Chapter 10: Views 302 columns to a
- Page 342 and 343: Chapter 10: Views Try It Out Using
- Page 344 and 345: Chapter 10: Views 306 soh.SalesOrde
- Page 346 and 347: Chapter 10: Views AW00000676 43659
- Page 348 and 349: Chapter 10: Views NULL values will
- Page 350 and 351: Chapter 10: Views Editing V iews wi
- Page 352 and 353: Chapter 10: Views 314 There are fou
- Page 354 and 355: Chapter 10: Views Editing Views in
- Page 356 and 357: Chapter 10: Views 318 In addition,
- Page 358 and 359: Chapter 10: Views 320 from the firs
- Page 360 and 361: Chapter 10: Views You can get the y
- Page 363 and 364: 11 Writing Scripts and Batches Whet
- Page 365 and 366: Next we have a DECLARE statement to
- Page 367 and 368: I’m not going to pick any bones a
- Page 369 and 370: Using @@IDENTITY @@IDENTITY is one
- Page 371 and 372: How It Works What we’re doing in
- Page 373 and 374: DECLARE @RowCount int; --Notice the
- Page 375 and 376: When the editing tool encounters a
- Page 377 and 378: When you think about it, this seems
- Page 379 and 380: So, let’s try a quick query direc
- Page 381 and 382: We now have our text file source fo
Chapter 9: <strong>SQL</strong> <strong>Server</strong> Storage and Index Structures<br />
Now, the question is how do we use this information once we have it? The answer is, of course, that it<br />
depends.<br />
Using the output from our fragmentation query, we have a decent idea of whether our database is full,<br />
fragmented, or somewhere in between (the latter is, most likely, what we want to see). If we’re running<br />
an OLAP system, then having full pages would be great — fragmentation would bring on depression.<br />
For an OLTP system, we would want much the opposite (although only to a point).<br />
So, how do we take care of the problem? To answer that, we need to look into the concept of index<br />
rebuilding and fillfactors.<br />
ALTER INDEX and FILLFACTOR<br />
294<br />
Stat What It Means<br />
Logical Scan<br />
Fragmentation<br />
Extent Scan<br />
Fragmentation<br />
The percentage of pages that are out of order as checked by scanning the leaf<br />
pages of an index. Only relevant to scans related to a clustered table. An out-oforder<br />
page is one for which the next page indicated in the index allocation map<br />
(IAM) is different from that pointed to by the next page pointer in the leaf page.<br />
This one is telling whether an extent is not physically located next to the extent<br />
that it should be logically located next to. This just means that the leaf pages of<br />
your index are not physically in order (though they still can be logically), and<br />
it shows what percentage of the extents this problem pertains to.<br />
As we saw earlier in the chapter, <strong>SQL</strong> <strong>Server</strong> gives us an option for controlling just how full our leaf<br />
level pages are and, if we choose, another option to deal with non-leaf level pages. Unfortunately, these<br />
are proactive options. They are applied once, and then you need to reapply them as necessary by<br />
rebuilding or reorganizing your indexes to reapply the options.<br />
To rebuild indexes, we can either drop them and create them again (if you do, using the DROP_EXISTING<br />
option usually is a good idea), or make use of the ALTER INDEX command with the REBUILD option.<br />
Keep in mind, however, what was said previously about rebuilding indexes — unless you have the<br />
ONLINE option available, rebuilding indexes takes the index (and possibly the entire table) totally offline<br />
until the rebuild is complete. In general, reorganizing is going to be a better option.<br />
A reorg affects only the leaf level of the index (where most of the issue is likely to be anyway) and keeps<br />
the index online while the reorg is taking place. Reorganizing your indexes restructures all the leaf level<br />
information in those indexes, and reestablishes a base percentage that your pages are full. If the index in<br />
question is a clustered index, then the physical data is also reorganized. Unfortunately, REORGANIZE<br />
does not allow for the change of several index settings, such as FILLFACTOR.<br />
If the index has not had a specific fillfactor specified, the pages will be reconstituted to be full, minus<br />
two records. Just as with the CREATE TABLE syntax, you can set the FILLFACTOR to be any value between<br />
1 and 100 as long as you are doing a full rebuild (as opposed to just a reorg). This number will be the<br />
percent that your pages are full once the database reorganization is complete. Remember, though, that as<br />
your pages split, your data will still be distributed 50-50 between the two pages — you cannot control<br />
the fill percentage on an ongoing basis other than by regularly rebuilding the indexes.