{"id":609,"date":"2012-01-31T11:00:18","date_gmt":"2012-01-31T16:00:18","guid":{"rendered":"http:\/\/sqlity.net\/en\/?p=609"},"modified":"2014-11-13T14:00:15","modified_gmt":"2014-11-13T19:00:15","slug":"the-performance-impact-of-forwarded-records-on-table-scans","status":"publish","type":"post","link":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/","title":{"rendered":"The Performance Impact of Forwarded Records on Table Scans"},"content":{"rendered":"<div>\n<p>\nForwarded records are a mechanism that SQL Server employs to reduce the amount of maintenance work for indexes on a table without a clustered index. During an update of a record in a table that does not have a clustered index, an increase in size might prevent the record to fit on its current page. If that happens, a forwarding pointer is created in the current page and the record is moved to a new location.\n<\/p>\n<p>\nIt is well known that such forwarded records will cause each RID-Lookup operation that encounters one to have to read a second page. If you are doing a filtered index scan followed by an RID-Lookup this can potentially double the amount of work necessary to retrieve all rows.\n<\/p>\n<p>\nWhat is less well known is the fact, that such forwarded records can significantly impact the performance of a simple table scan as well. In this article I will show you why this happens.\n<\/p>\n<h3>Terminology<\/h3>\n<p>\nTo explain the way SQL Server handles forwarded records during a table scan, I am first going to rehash some storage basics.\n<\/p>\n<p>\nSQL Server knows two ways to organize the data in a table on disk. One is the Clustered Index and the other one the Heap. In a Clustered Index data is organized in a B+Tree structure allowing for fast access based on the Clustered Index Key. In a Heap on the other hand the data is not sorted or linked in any way. Any new row is inserted into the table in any free space big enough to hold the row.\n<\/p>\n<p>\nIn both cases the smallest unit of storage and access is a Page. Every piece of data SQL Server needs to store on disk is organized in blocks called pages. Each page is exactly 8192 Bytes in size. The only exception to this rule are the log files. Log data is stored in a structure called virtual log file and those are not part of today's discussion.\n<\/p>\n<p>\nIndexes created on a Heap use a physical address to point from the index record to the underlying data record. This address consists of the file number, the number of the page that contains the record within that file and the slot number inside that page.\n<\/p>\n<h3>Forwarded Records<\/h3>\n<p>\nWhen a record with variable length data type columns is updated, its size might increase. If the page it is stored in is filled already, the updated record might need to be moved to a new page. If that happens, all pointers in any index on that table addressing the moved row now point to the wrong (old) place. There are two ways to handle this situation: Update all indexes with the new location or put a special record in the old place that \"forwards\" to the new location.\n<\/p>\n<p>\nGoing through all existing indexes can be extensively resource intensive. For that reason SQL Server is using the second option to put a forwarding record in the old place.\n<\/p>\n<p>\nSuch a forwarding record links to the new physical address of the actual data. The new record also contains a pointer back to the forwarding record. This back-pointer allows the forwarding record to get updated in case the data record has to move again or in case it gets deleted which causes the forwarding record to be deleted as well. Updating the forwarding records in cases of repeated data record moves prevents long forwarding chains. Instead there is always only at max on hop.\n<\/p>\n<p>\nIn the case of an RID-Lookup SQL Server has to follow those forwarding records to get to the actual data record. This causes an additional (logical) page read for each forwarding record encountered.\n<\/p>\n<p>\nDuring a table scan on the other hand each page will be read anyway so SQL Server could just ignore all forwarding records. That however could cause reading inconsistencies. Rows that are updated after the scan started and before it finishes could be missed entirely by the scan, if the record gets moved to a page that was scanned already. For that reason SQL Server follows each forwarding record immediately. This not only causes an additional read right there, is also turns the sequential read of all pages in allocation order into a succession of random reads, hurting performance potentially even more.\n<\/p>\n<h3>Demonstration<\/h3>\n<p>\nTo demonstrate this behavior let us set up two tables dbo.ForwardSmall and dbo.NoForwardSmall as well as a Procedure dbo.ChangeRow to help with the creation of forwarded records:\n<\/p>\n<div>\n[sql]\nIF OBJECT_ID('dbo.ForwardSmall') IS NOT NULL DROP TABLE dbo.ForwardSmall;<br \/>\nCREATE TABLE dbo.ForwardSmall(Id INT ,F VARCHAR(8000))<br \/>\nGO<br \/>\nIF OBJECT_ID('dbo.NoForwardSmall') IS NOT NULL DROP TABLE dbo.NoForwardSmall;<br \/>\nCREATE TABLE dbo.NoForwardSmall(Id INT ,F VARCHAR(8000))<br \/>\nGO<\/p>\n<p>IF OBJECT_ID('dbo.ChangeRow') IS NOT NULL DROP PROCEDURE dbo.ChangeRow;<br \/>\nGO<br \/>\nCREATE PROCEDURE dbo.ChangeRow<br \/>\n@Id INT,<br \/>\n@Size INT<br \/>\nAS<br \/>\nBEGIN<br \/>\n  SET NOCOUNT ON;<br \/>\n  MERGE dbo.ForwardSmall fs<br \/>\n  USING (SELECT @Id,REPLICATE('X',@Size)) x(Id,F)<br \/>\n  ON fs.Id = x.Id<br \/>\n  WHEN MATCHED THEN<br \/>\n    UPDATE SET fs.F = x.F<br \/>\n  WHEN NOT MATCHED THEN<br \/>\n    INSERT (Id,F)VALUES(x.Id,x.F);<br \/>\nEND<br \/>\nGO<br \/>\n[\/sql]\n<\/p><\/div>\n<p>\nThe procedure will take an Id parameter as well as a size parameter. It uses to merge command to either insert or update the record with the given Id value. The F column will be valued with a string of length @Size.\n<\/p>\n<p>\nThe following script will create 16 rows in the table dbo.ForwardSmall and then update those records to create forwarded records.\n<\/p>\n<div>\n[sql]\nEXEC dbo.ChangeRow 11,900;<br \/>\nEXEC dbo.ChangeRow 12,900;<br \/>\nEXEC dbo.ChangeRow 13,900;<br \/>\nEXEC dbo.ChangeRow 14,900;<br \/>\nEXEC dbo.ChangeRow 15,900;<br \/>\nEXEC dbo.ChangeRow 16,900;<br \/>\nEXEC dbo.ChangeRow 17,900;<br \/>\nEXEC dbo.ChangeRow 18,900;<\/p>\n<p>EXEC dbo.ChangeRow 21,900;<br \/>\nEXEC dbo.ChangeRow 22,900;<br \/>\nEXEC dbo.ChangeRow 23,900;<br \/>\nEXEC dbo.ChangeRow 24,900;<br \/>\nEXEC dbo.ChangeRow 25,900;<br \/>\nEXEC dbo.ChangeRow 26,900;<br \/>\nEXEC dbo.ChangeRow 27,900;<br \/>\nEXEC dbo.ChangeRow 28,900;<br \/>\n--------------------------<br \/>\nEXEC dbo.ChangeRow 27,0;<br \/>\nEXEC dbo.ChangeRow 28,0;<br \/>\nEXEC dbo.ChangeRow 18,1800;<br \/>\nEXEC dbo.ChangeRow 28,900;<br \/>\nEXEC dbo.ChangeRow 18,900;<\/p>\n<p>EXEC dbo.ChangeRow 26,0;<br \/>\nEXEC dbo.ChangeRow 17,1800;<br \/>\nEXEC dbo.ChangeRow 27,900;<br \/>\nEXEC dbo.ChangeRow 17,900;<\/p>\n<p>EXEC dbo.ChangeRow 25,0;<br \/>\nEXEC dbo.ChangeRow 16,1800;<br \/>\nEXEC dbo.ChangeRow 26,900;<br \/>\nEXEC dbo.ChangeRow 16,900;<\/p>\n<p>EXEC dbo.ChangeRow 24,0;<br \/>\nEXEC dbo.ChangeRow 15,1800;<br \/>\nEXEC dbo.ChangeRow 25,900;<br \/>\nEXEC dbo.ChangeRow 15,900;<\/p>\n<p>EXEC dbo.ChangeRow 23,0;<br \/>\nEXEC dbo.ChangeRow 14,1800;<br \/>\nEXEC dbo.ChangeRow 24,900;<br \/>\nEXEC dbo.ChangeRow 14,900;<\/p>\n<p>EXEC dbo.ChangeRow 22,0;<br \/>\nEXEC dbo.ChangeRow 13,1800;<br \/>\nEXEC dbo.ChangeRow 23,900;<br \/>\nEXEC dbo.ChangeRow 13,900;<\/p>\n<p>EXEC dbo.ChangeRow 21,0;<br \/>\nEXEC dbo.ChangeRow 12,1800;<br \/>\nEXEC dbo.ChangeRow 22,1499;<br \/>\nEXEC dbo.ChangeRow 12,780;<\/p>\n<p>EXEC dbo.ChangeRow 11,910;<\/p>\n<p>EXEC dbo.ChangeRow 22,900;<br \/>\nEXEC dbo.ChangeRow 21,910;<br \/>\n[\/sql]\n<\/p><\/div>\n<p>\nEach record starts out with ~950 bytes, so the 16 records will fit into two pages. From there the records are updated in a way so that each of them ends up on the other page with a forwarding record in its old place.\n<\/p>\n<p>\nNow lets put the exact same data into the dbo.NoForwardSmall table:\n<\/p>\n<div>\n[sql]\nINSERT INTO dbo.NoForwardSmall<br \/>\nSELECT * FROM dbo.ForwardSmall;<br \/>\n[\/sql]\n<\/div>\n<p>\nThis again requires two pages, but this time no forwarded records are created.\n<\/p>\n<p>\nTo confirm, we can use the following query using the sys.dm_db_index_physical_stats DMF:\n<\/p>\n<div>\n[sql]\nSELECT OBJECT_SCHEMA_NAME(object_id)+'.'+OBJECT_NAME(object_id) Tbl,index_type_desc,alloc_unit_type_desc,page_count,record_count,forwarded_record_count<br \/>\nFROM sys.dm_db_index_physical_stats(DB_ID(),NULL,NULL,NULL,'detailed') ps<br \/>\nWHERE object_id IN (OBJECT_ID('dbo.ForwardSmall'),OBJECT_ID('dbo.NoForwardSmall'));<br \/>\n[\/sql]\n<\/div>\n<p>\nThis query returns the number of pages, the total number of records and the number of forwarded records for each table:\n<\/p>\n<div>\n<style type=\"text\/css\">\ntable.tableizer-table {border: 1px solid #CCC; font-family: Arial, Helvetica, sans-serif; font-size: 12px;} .tableizer-table td {padding: 4px; margin: 3px; border: 1px solid #ccc;}\n.tableizer-table th {background-color: #104E8B; color: #FFF; font-weight: bold;}\n<\/style>\n<table class=\"tableizer-table\">\n<tr class=\"tableizer-firstrow\">\n<th>Tbl<\/th>\n<th>index_type_desc<\/th>\n<th>alloc_unit_type_desc<\/th>\n<th>page_count<\/th>\n<th>record_count<\/th>\n<th>forwarded_record_count<\/th>\n<\/tr>\n<tr>\n<td>dbo.ForwardSmall<\/td>\n<td>HEAP<\/td>\n<td>IN_ROW_DATA<\/td>\n<td>2<\/td>\n<td>32<\/td>\n<td>16<\/td>\n<\/tr>\n<tr>\n<td>dbo.NoForwardSmall<\/td>\n<td>HEAP<\/td>\n<td>IN_ROW_DATA<\/td>\n<td>2<\/td>\n<td>16<\/td>\n<td>0<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>\nNow let us look at what happens during a table scan:\n<\/p>\n<div>\n[sql]\nSET STATISTICS IO ON;<br \/>\nSELECT * FROM dbo.NoForwardSmall;<br \/>\nGO<br \/>\nSELECT * FROM dbo.ForwardSmall;<br \/>\nSET STATISTICS IO OFF;<br \/>\n[\/sql]\n<\/div>\n<p>\nThis produces the following output:\n<\/p>\n<div>\n<pre>\r\n(16 row(s) affected)\r\nTable 'NoForwardSmall'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n\r\n(16 row(s) affected)\r\nTable 'ForwardSmall'. Scan count 1, logical reads 18, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.\r\n<\/pre>\n<\/div>\n<p>\nScanning the dbo.NoForwardSmall table caused 2 logical reads - one for each page of the table. Scanning the dbo.ForwardSmall table however caused 18 logical reads. That is almost ten times more. Each of the 16 records caused an additional page read.\n<\/p>\n<h3>Conclusion<\/h3>\n<p>\nThis article showed that SQL Server follows each forwarding record it encounters right away. This not only happens in the case of an RID-Lookup but also in the case of a table scan. These additional reads can present a significant performance impact. If you have a decently sized table with variable length columns and with regular update activity, add this behavior to the list of reasons why the table really should have a clustered index.\n<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Forwarded records are a mechanism that SQL Server employs to reduce the amount of maintenance work for indexes on a table without a clustered index. During an update of a record in a table that does not have a clustered <a href=\"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/\">[more&#8230;]<\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[5,19,14],"tags":[],"class_list":["post-609","post","type-post","status-publish","format-standard","hentry","category-general","category-performance","category-sql-server-internals"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Performance Impact of Forwarded Records on Table Scans - sqlity.net<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Performance Impact of Forwarded Records on Table Scans - sqlity.net\" \/>\n<meta property=\"og:description\" content=\"Forwarded records are a mechanism that SQL Server employs to reduce the amount of maintenance work for indexes on a table without a clustered index. During an update of a record in a table that does not have a clustered [more...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/\" \/>\n<meta property=\"og:site_name\" content=\"sqlity.net\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/sqlity.net\" \/>\n<meta property=\"article:published_time\" content=\"2012-01-31T16:00:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-11-13T19:00:15+00:00\" \/>\n<meta name=\"author\" content=\"Sebastian Meine\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@sqlity\" \/>\n<meta name=\"twitter:site\" content=\"@sqlity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sebastian Meine\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/\"},\"author\":{\"name\":\"Sebastian Meine\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#\\\/schema\\\/person\\\/bcffd8c572bc2f1bd10fdba80135e53c\"},\"headline\":\"The Performance Impact of Forwarded Records on Table Scans\",\"datePublished\":\"2012-01-31T16:00:18+00:00\",\"dateModified\":\"2014-11-13T19:00:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/\"},\"wordCount\":1422,\"commentCount\":0,\"articleSection\":[\"General\",\"Performance\",\"SQL Server Internals\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/\",\"url\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/\",\"name\":\"The Performance Impact of Forwarded Records on Table Scans - sqlity.net\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#website\"},\"datePublished\":\"2012-01-31T16:00:18+00:00\",\"dateModified\":\"2014-11-13T19:00:15+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#\\\/schema\\\/person\\\/bcffd8c572bc2f1bd10fdba80135e53c\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/609\\\/the-performance-impact-of-forwarded-records-on-table-scans\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/sqlity.net\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The Performance Impact of Forwarded Records on Table Scans\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/sqlity.net\\\/en\\\/\",\"name\":\"sqlity.net\",\"description\":\"Quality for SQL\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/sqlity.net\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#\\\/schema\\\/person\\\/bcffd8c572bc2f1bd10fdba80135e53c\",\"name\":\"Sebastian Meine\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g\",\"caption\":\"Sebastian Meine\"},\"sameAs\":[\"http:\\\/\\\/sqlity.net\",\"https:\\\/\\\/x.com\\\/sqlity\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Performance Impact of Forwarded Records on Table Scans - sqlity.net","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/","og_locale":"en_US","og_type":"article","og_title":"The Performance Impact of Forwarded Records on Table Scans - sqlity.net","og_description":"Forwarded records are a mechanism that SQL Server employs to reduce the amount of maintenance work for indexes on a table without a clustered index. During an update of a record in a table that does not have a clustered [more...]","og_url":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/","og_site_name":"sqlity.net","article_publisher":"https:\/\/www.facebook.com\/sqlity.net","article_published_time":"2012-01-31T16:00:18+00:00","article_modified_time":"2014-11-13T19:00:15+00:00","author":"Sebastian Meine","twitter_card":"summary_large_image","twitter_creator":"@sqlity","twitter_site":"@sqlity","twitter_misc":{"Written by":"Sebastian Meine","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/#article","isPartOf":{"@id":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/"},"author":{"name":"Sebastian Meine","@id":"https:\/\/sqlity.net\/en\/#\/schema\/person\/bcffd8c572bc2f1bd10fdba80135e53c"},"headline":"The Performance Impact of Forwarded Records on Table Scans","datePublished":"2012-01-31T16:00:18+00:00","dateModified":"2014-11-13T19:00:15+00:00","mainEntityOfPage":{"@id":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/"},"wordCount":1422,"commentCount":0,"articleSection":["General","Performance","SQL Server Internals"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/","url":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/","name":"The Performance Impact of Forwarded Records on Table Scans - sqlity.net","isPartOf":{"@id":"https:\/\/sqlity.net\/en\/#website"},"datePublished":"2012-01-31T16:00:18+00:00","dateModified":"2014-11-13T19:00:15+00:00","author":{"@id":"https:\/\/sqlity.net\/en\/#\/schema\/person\/bcffd8c572bc2f1bd10fdba80135e53c"},"breadcrumb":{"@id":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/sqlity.net\/en\/609\/the-performance-impact-of-forwarded-records-on-table-scans\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/sqlity.net\/en\/"},{"@type":"ListItem","position":2,"name":"The Performance Impact of Forwarded Records on Table Scans"}]},{"@type":"WebSite","@id":"https:\/\/sqlity.net\/en\/#website","url":"https:\/\/sqlity.net\/en\/","name":"sqlity.net","description":"Quality for SQL","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/sqlity.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/sqlity.net\/en\/#\/schema\/person\/bcffd8c572bc2f1bd10fdba80135e53c","name":"Sebastian Meine","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g","caption":"Sebastian Meine"},"sameAs":["http:\/\/sqlity.net","https:\/\/x.com\/sqlity"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2wXuw-9P","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/posts\/609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/comments?post=609"}],"version-history":[{"count":0,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/posts\/609\/revisions"}],"wp:attachment":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/media?parent=609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/categories?post=609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/tags?post=609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}