{"id":503,"date":"2011-12-08T21:17:00","date_gmt":"2011-12-08T21:17:00","guid":{"rendered":"\/blogs\/jonathan\/post\/Tracking-Problematic-Pages-Splits-in-SQL-Server-2012-Extended-Events-e28093-No-Really-This-Time!.aspx"},"modified":"2017-04-13T14:41:27","modified_gmt":"2017-04-13T18:41:27","slug":"tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/","title":{"rendered":"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time!"},"content":{"rendered":"<p>Just over a year ago I blogged about the <a href=\"https:\/\/www.sqlskills.com\/blogs\/jonathan\/an-xevent-a-day-27-of-31-the-future-tracking-page-splits-in-sql-server-denali-ctp1\/\" target=\"_blank\">enhancements that were made to the sqlserver.page_split Event in SQL Server 2012<\/a> to make it easier to identify what the splitting object was and the type of split that was being performed.&#160; Sadly what I discovered writing that post was that even with the extra information about the split type, the event didn\u2019t give you enough information to really focus on the problematic splits that lead to fragmentation and page density issues in the database.&#160; I didn\u2019t do a whole lot with this again until recently when a question was posted by Ami Levin (<a href=\"http:\/\/sql-server-tuning.com\/cgi-sys\/suspendedpage.cgi\" target=\"_blank\">Blog<\/a> | <a href=\"https:\/\/mobile.twitter.com\/signup#!\/DBSophic\" target=\"_blank\">Twitter<\/a>) on the MVP email list that commented that the page_split event was broken in SQL Server 2012 based on a presentation he\u2019d seen by Guy Glantser (<a href=\"http:\/\/www.madeiradata.com\">Blog <\/a>| <a href=\"https:\/\/mobile.twitter.com\/guy_glantser\">Twitter<\/a>). <\/p>\n<p>Let me start off by saying, the event isn\u2019t broken, it tracks page splits, but it doesn\u2019t differentiate between an end page split that occurs for an ever increasing index, versus a mid-page split for a random index that leads to fragmentation and page density issues in the database.&#160; Both of these are technically splits inside the storage engine, even if we as DBA\u2019s don\u2019t really care about the end-page split for a increasing key value like an IDENTITY column in the database.&#160; I had Ami pass my information along to the presenter and we traded a few emails on the subject of tracking splits with the specific focus on trying to pull out the mid-page, fragmenting splits.&#160; While going through things for the third time, it dawned on me that this is incredibly simple, based one of the demo\u2019s that was sent to me.&#160; Just over a year ago, <a href=\"https:\/\/www.sqlskills.com\/blogs\/jonathan\/an-xevent-a-day-22-of-31-the-future-fn_dblog-no-more-tracking-transaction-log-activity-in-denali\/\" target=\"_blank\">I also blogged about tracking transaction log activity in SQL Server 2012<\/a> using the sqlserver.transaction_log event, which can be used to track mid-page splits in a database.<\/p>\n<p>Last year when I wrote about the sqlserver.transaction_log event, there were 10 columns output by the event in CTP1, but as of RC0, the events output has changed and only 9 columns are output by the event.<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"kwrd\">SELECT<\/span> \r\n    oc.name, \r\n    oc.type_name, \r\n    oc.description\r\n<span class=\"kwrd\">FROM<\/span> sys.dm_xe_packages <span class=\"kwrd\">AS<\/span> p\r\n<span class=\"kwrd\">INNER<\/span> <span class=\"kwrd\">JOIN<\/span> sys.dm_xe_objects <span class=\"kwrd\">AS<\/span> o\r\n    <span class=\"kwrd\">ON<\/span> p.guid = o.package_guid\r\n<span class=\"kwrd\">INNER<\/span> <span class=\"kwrd\">JOIN<\/span> sys.dm_xe_object_columns <span class=\"kwrd\">AS<\/span> oc\r\n    <span class=\"kwrd\">ON<\/span> oc.object_name = o.name\r\n        <span class=\"kwrd\">AND<\/span> oc.object_package_guid = o.package_guid\r\n<span class=\"kwrd\">WHERE<\/span> o.name = <span class=\"str\">'transaction_log'<\/span>\r\n  <span class=\"kwrd\">AND<\/span> oc.column_type = <span class=\"str\">'data'<\/span>;<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p><a href=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/28d1f4d8\/image.png\" target=\"_blank\"><img fetchpriority=\"high\" decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png\" width=\"644\" height=\"152\" \/><\/a><\/p>\n<p>For the purposes of identifying the mid-page splits, we want to look at the <strong>operation<\/strong> column that is output by the event, which contains the specific operation being logged.&#160; In the case of a mid-page split occurring, the operation will be a LOP_DELETE_SPLIT, which marks the delete of rows from a page as a result of the split.&#160; To build our event session, we are going to need the map_key for the LOP_DELETE_SPLIT log_op map.&#160; This can be obtained from the sys.dm_xe_map_values DMV:<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"kwrd\">SELECT<\/span> *\r\n<span class=\"kwrd\">FROM<\/span> sys.dm_xe_map_values\r\n<span class=\"kwrd\">WHERE<\/span> name = <span class=\"str\">'log_op'<\/span>\r\n  <span class=\"kwrd\">AND<\/span> map_value = <span class=\"str\">'LOP_DELETE_SPLIT'<\/span>;<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p>With the map_key value, we have a couple of ways to collect the information with our targets.&#160; We could collect everything into an event_file, but that doesn\u2019t really make sense for this event.&#160; Instead the best target for this type of information is the histogram target which will bucket our results based on how we configure the target and tell us how frequently the event fires based on our bucketing criteria.&#160; If we don\u2019t know anything about the server in question, we can start off with a very general event session that has a predicate on the operation only, and then aggregate the information in the histogram target based on the database_id to find the databases that have the most mid-page splits occurring in them in the instance.<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"rem\">-- If the Event Session exists DROP it<\/span>\r\n<span class=\"kwrd\">IF<\/span> <span class=\"kwrd\">EXISTS<\/span> (<span class=\"kwrd\">SELECT<\/span> 1 \r\n            <span class=\"kwrd\">FROM<\/span> sys.server_event_sessions \r\n            <span class=\"kwrd\">WHERE<\/span> name = <span class=\"str\">'SQLskills_TrackPageSplits'<\/span>)\r\n    <span class=\"kwrd\">DROP<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits] <span class=\"kwrd\">ON<\/span> SERVER\r\n\r\n<span class=\"rem\">-- Create the Event Session to track LOP_DELETE_SPLIT transaction_log operations in the server<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits]\r\n<span class=\"kwrd\">ON<\/span>    SERVER\r\n<span class=\"kwrd\">ADD<\/span> EVENT sqlserver.transaction_log(\r\n    <span class=\"kwrd\">WHERE<\/span> <span class=\"kwrd\">operation<\/span> = 11  <span class=\"rem\">-- LOP_DELETE_SPLIT <\/span>\r\n)\r\n<span class=\"kwrd\">ADD<\/span> TARGET package0.histogram(\r\n    <span class=\"kwrd\">SET<\/span> filtering_event_name = <span class=\"str\">'sqlserver.transaction_log'<\/span>,\r\n        source_type = 0, <span class=\"rem\">-- Event Column<\/span>\r\n        source = <span class=\"str\">'database_id'<\/span>);\r\n<span class=\"kwrd\">GO<\/span>\r\n        \r\n<span class=\"rem\">-- Start the Event Session<\/span>\r\n<span class=\"kwrd\">ALTER<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits]\r\n<span class=\"kwrd\">ON<\/span> SERVER\r\n<span class=\"kwrd\">STATE<\/span>=<span class=\"kwrd\">START<\/span>;\r\n<span class=\"kwrd\">GO<\/span><\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p>This event session will allow you to track the worst splitting database on the server, and the event data can be parsed out of the histogram target.&#160; To demonstrate this, we can create a database that has tables and indexes prone to mid-page splits and run a default workload to test the event session:<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"kwrd\">USE<\/span> [master];\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">-- Drop the PageSplits database if it exists<\/span>\r\n<span class=\"kwrd\">IF<\/span> DB_ID(<span class=\"str\">'PageSplits'<\/span>) <span class=\"kwrd\">IS<\/span> <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span>\r\n<span class=\"kwrd\">BEGIN<\/span>\r\n    <span class=\"kwrd\">ALTER<\/span> <span class=\"kwrd\">DATABASE<\/span> PageSplits <span class=\"kwrd\">SET<\/span> SINGLE_USER <span class=\"kwrd\">WITH<\/span> <span class=\"kwrd\">ROLLBACK<\/span> <span class=\"kwrd\">IMMEDIATE<\/span>;\r\n    <span class=\"kwrd\">DROP<\/span> <span class=\"kwrd\">DATABASE<\/span> PageSplits;\r\n<span class=\"kwrd\">END<\/span>\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">-- Create the database<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> <span class=\"kwrd\">DATABASE<\/span> PageSplits\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"kwrd\">USE<\/span> [PageSplits]\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">-- Create a bad splitting clustered index table<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> <span class=\"kwrd\">TABLE<\/span> BadSplitsPK\r\n( ROWID UNIQUEIDENTIFIER <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span> <span class=\"kwrd\">DEFAULT<\/span> NEWID() <span class=\"kwrd\">PRIMARY<\/span> <span class=\"kwrd\">KEY<\/span>,\r\n  ColVal <span class=\"kwrd\">INT<\/span> <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span> <span class=\"kwrd\">DEFAULT<\/span> (RAND()*1000),\r\n  ChangeDate DATETIME2 <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span> <span class=\"kwrd\">DEFAULT<\/span> <span class=\"kwrd\">CURRENT_TIMESTAMP<\/span>);\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">--  This index should mid-split based on the DEFAULT column value<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> <span class=\"kwrd\">INDEX<\/span> IX_BadSplitsPK_ColVal <span class=\"kwrd\">ON<\/span> BadSplitsPK (ColVal);\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">--  This index should end-split based on the DEFAULT column value<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> <span class=\"kwrd\">INDEX<\/span> IX_BadSplitsPK_ChangeDate <span class=\"kwrd\">ON<\/span> BadSplitsPK (ChangeDate);\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">-- Create a table with an increasing clustered index<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> <span class=\"kwrd\">TABLE<\/span> EndSplitsPK\r\n( ROWID <span class=\"kwrd\">INT<\/span> <span class=\"kwrd\">IDENTITY<\/span> <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span> <span class=\"kwrd\">PRIMARY<\/span> <span class=\"kwrd\">KEY<\/span>,\r\n  ColVal <span class=\"kwrd\">INT<\/span> <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span> <span class=\"kwrd\">DEFAULT<\/span> (RAND()*1000),\r\n  ChangeDate DATETIME2 <span class=\"kwrd\">NOT<\/span> <span class=\"kwrd\">NULL<\/span> <span class=\"kwrd\">DEFAULT<\/span> DATEADD(mi, RAND()*-1000, <span class=\"kwrd\">CURRENT_TIMESTAMP<\/span>));\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">--  This index should mid-split based on the DEFAULT column value<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> <span class=\"kwrd\">INDEX<\/span> IX_EndSplitsPK_ChangeDate <span class=\"kwrd\">ON<\/span> EndSplitsPK (ChangeDate);\r\n<span class=\"kwrd\">GO<\/span>\r\n<span class=\"rem\">-- Insert the default values repeatedly into the tables<\/span>\r\n<span class=\"kwrd\">WHILE<\/span> 1=1\r\n<span class=\"kwrd\">BEGIN<\/span>\r\n    INSERT <span class=\"kwrd\">INTO<\/span> dbo.BadSplitsPK <span class=\"kwrd\">DEFAULT<\/span> <span class=\"kwrd\">VALUES<\/span>;\r\n    INSERT <span class=\"kwrd\">INTO<\/span> dbo.EndSplitsPK <span class=\"kwrd\">DEFAULT<\/span> <span class=\"kwrd\">VALUES<\/span>;\r\n    <span class=\"kwrd\">WAITFOR<\/span> DELAY <span class=\"str\">'00:00:00.005'<\/span>;\r\n<span class=\"kwrd\">END<\/span>\r\nGO<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p>If we startup this workload and allow it to run for a couple of minutes, we can then query the histogram target for our session to find the database that has the mid-page splits occurring.<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"rem\">-- Query the target data to identify the worst splitting database_id<\/span>\r\n<span class=\"kwrd\">SELECT<\/span> \r\n    n.<span class=\"kwrd\">value<\/span>(<span class=\"str\">'(value)[1]'<\/span>, <span class=\"str\">'bigint'<\/span>) <span class=\"kwrd\">AS<\/span> database_id,\r\n    DB_NAME(n.<span class=\"kwrd\">value<\/span>(<span class=\"str\">'(value)[1]'<\/span>, <span class=\"str\">'bigint'<\/span>)) <span class=\"kwrd\">AS<\/span> database_name,\r\n    n.<span class=\"kwrd\">value<\/span>(<span class=\"str\">'(@count)[1]'<\/span>, <span class=\"str\">'bigint'<\/span>) <span class=\"kwrd\">AS<\/span> split_count\r\n<span class=\"kwrd\">FROM<\/span>\r\n(<span class=\"kwrd\">SELECT<\/span> <span class=\"kwrd\">CAST<\/span>(target_data <span class=\"kwrd\">as<\/span> XML) target_data\r\n <span class=\"kwrd\">FROM<\/span> sys.dm_xe_sessions <span class=\"kwrd\">AS<\/span> s \r\n <span class=\"kwrd\">JOIN<\/span> sys.dm_xe_session_targets t\r\n     <span class=\"kwrd\">ON<\/span> s.address = t.event_session_address\r\n <span class=\"kwrd\">WHERE<\/span> s.name = <span class=\"str\">'SQLskills_TrackPageSplits'<\/span>\r\n  <span class=\"kwrd\">AND<\/span> t.target_name = <span class=\"str\">'histogram'<\/span> ) <span class=\"kwrd\">as<\/span> tab\r\n<span class=\"kwrd\">CROSS<\/span> APPLY target_data.nodes(<span class=\"str\">'HistogramTarget\/Slot'<\/span>) <span class=\"kwrd\">as<\/span> q(n)<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p><a href=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/5d3271e9\/image.png\"><img decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/75c20f39\/image_thumb.png\" width=\"281\" height=\"51\" \/><\/a><\/p>\n<p>With the database_id of the worst splitting database, we can then change our event session configuration to only look at this database, and then change our histogram target configuration to bucket on the alloc_unit_id so that we can then track down the worst splitting indexes in the database experiencing the worst mid-page splits.<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"rem\">-- Drop the Event Session so we can recreate it <\/span>\r\n<span class=\"rem\">-- to focus on the highest splitting database<\/span>\r\n<span class=\"kwrd\">DROP<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits] \r\n<span class=\"kwrd\">ON<\/span> SERVER\r\n\r\n<span class=\"rem\">-- Create the Event Session to track LOP_DELETE_SPLIT transaction_log operations in the server<\/span>\r\n<span class=\"kwrd\">CREATE<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits]\r\n<span class=\"kwrd\">ON<\/span>    SERVER\r\n<span class=\"kwrd\">ADD<\/span> EVENT sqlserver.transaction_log(\r\n    <span class=\"kwrd\">WHERE<\/span> <span class=\"kwrd\">operation<\/span> = 11  <span class=\"rem\">-- LOP_DELETE_SPLIT <\/span>\r\n      <span class=\"kwrd\">AND<\/span> database_id = 8 <span class=\"rem\">-- CHANGE THIS BASED ON TOP SPLITTING DATABASE!<\/span>\r\n)\r\n<span class=\"kwrd\">ADD<\/span> TARGET package0.histogram(\r\n    <span class=\"kwrd\">SET<\/span> filtering_event_name = <span class=\"str\">'sqlserver.transaction_log'<\/span>,\r\n        source_type = 0, <span class=\"rem\">-- Event Column<\/span>\r\n        source = <span class=\"str\">'alloc_unit_id'<\/span>);\r\n<span class=\"kwrd\">GO<\/span>\r\n\r\n<span class=\"rem\">-- Start the Event Session Again<\/span>\r\n<span class=\"kwrd\">ALTER<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits]\r\n<span class=\"kwrd\">ON<\/span> SERVER\r\n<span class=\"kwrd\">STATE<\/span>=<span class=\"kwrd\">START<\/span>;\r\nGO<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p>With the new event session definition, we can now rerun our problematic workload for a 2 minute period and look at the worst splitting indexes based on the alloc_unit_id\u2019s that are in the histogram target:<\/p>\n<blockquote>\n<p>&#160;<\/p>\n<pre class=\"csharpcode\"><span class=\"rem\">-- Query Target Data to get the top splitting objects in the database:<\/span>\r\n<span class=\"kwrd\">SELECT<\/span>\r\n    o.name <span class=\"kwrd\">AS<\/span> table_name,\r\n    i.name <span class=\"kwrd\">AS<\/span> index_name,\r\n    tab.split_count,\r\n    i.fill_factor\r\n<span class=\"kwrd\">FROM<\/span> (    <span class=\"kwrd\">SELECT<\/span> \r\n            n.<span class=\"kwrd\">value<\/span>(<span class=\"str\">'(value)[1]'<\/span>, <span class=\"str\">'bigint'<\/span>) <span class=\"kwrd\">AS<\/span> alloc_unit_id,\r\n            n.<span class=\"kwrd\">value<\/span>(<span class=\"str\">'(@count)[1]'<\/span>, <span class=\"str\">'bigint'<\/span>) <span class=\"kwrd\">AS<\/span> split_count\r\n        <span class=\"kwrd\">FROM<\/span>\r\n        (<span class=\"kwrd\">SELECT<\/span> <span class=\"kwrd\">CAST<\/span>(target_data <span class=\"kwrd\">as<\/span> XML) target_data\r\n         <span class=\"kwrd\">FROM<\/span> sys.dm_xe_sessions <span class=\"kwrd\">AS<\/span> s \r\n         <span class=\"kwrd\">JOIN<\/span> sys.dm_xe_session_targets t\r\n             <span class=\"kwrd\">ON<\/span> s.address = t.event_session_address\r\n         <span class=\"kwrd\">WHERE<\/span> s.name = <span class=\"str\">'SQLskills_TrackPageSplits'<\/span>\r\n          <span class=\"kwrd\">AND<\/span> t.target_name = <span class=\"str\">'histogram'<\/span> ) <span class=\"kwrd\">as<\/span> tab\r\n        <span class=\"kwrd\">CROSS<\/span> APPLY target_data.nodes(<span class=\"str\">'HistogramTarget\/Slot'<\/span>) <span class=\"kwrd\">as<\/span> q(n)\r\n) <span class=\"kwrd\">AS<\/span> tab\r\n<span class=\"kwrd\">JOIN<\/span> sys.allocation_units <span class=\"kwrd\">AS<\/span> au\r\n    <span class=\"kwrd\">ON<\/span> tab.alloc_unit_id = au.allocation_unit_id\r\n<span class=\"kwrd\">JOIN<\/span> sys.partitions <span class=\"kwrd\">AS<\/span> p\r\n    <span class=\"kwrd\">ON<\/span> au.container_id = p.partition_id\r\n<span class=\"kwrd\">JOIN<\/span> sys.indexes <span class=\"kwrd\">AS<\/span> i\r\n    <span class=\"kwrd\">ON<\/span> p.object_id = i.object_id\r\n        <span class=\"kwrd\">AND<\/span> p.index_id = i.index_id\r\n<span class=\"kwrd\">JOIN<\/span> sys.objects <span class=\"kwrd\">AS<\/span> o\r\n    <span class=\"kwrd\">ON<\/span> p.object_id = o.object_id\r\n<span class=\"kwrd\">WHERE<\/span> o.is_ms_shipped = 0;<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p><a href=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/606459d1\/image.png\"><img decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/1bb7bf90\/image_thumb.png\" width=\"443\" height=\"90\" \/><\/a><\/p>\n<p>With this information we can now go back and change our FillFactor specifications and retest\/monitor the impact to determine whether we\u2019ve had the appropriate reduction in mid-page splits to accommodate the time between our index rebuild operations:<\/p>\n<blockquote>\n<pre class=\"csharpcode\"><span class=\"rem\">-- Change FillFactor based on split occurences<\/span>\r\n<span class=\"kwrd\">ALTER<\/span> <span class=\"kwrd\">INDEX<\/span> PK__BadSplit__97BD02EB726FCA55 <span class=\"kwrd\">ON<\/span> BadSplitsPK REBUILD <span class=\"kwrd\">WITH<\/span> (<span class=\"kwrd\">FILLFACTOR<\/span>=70)\r\n<span class=\"kwrd\">ALTER<\/span> <span class=\"kwrd\">INDEX<\/span> IX_BadSplitsPK_ColVal <span class=\"kwrd\">ON<\/span> BadSplitsPK REBUILD <span class=\"kwrd\">WITH<\/span> (<span class=\"kwrd\">FILLFACTOR<\/span>=70)\r\n<span class=\"kwrd\">ALTER<\/span> <span class=\"kwrd\">INDEX<\/span> IX_EndSplitsPK_ChangeDate <span class=\"kwrd\">ON<\/span> EndSplitsPK REBUILD <span class=\"kwrd\">WITH<\/span> (<span class=\"kwrd\">FILLFACTOR<\/span>=80)\r\n<span class=\"kwrd\">GO<\/span>\r\n\r\n<span class=\"rem\">-- Stop the Event Session to clear the target<\/span>\r\n<span class=\"kwrd\">ALTER<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits]\r\n<span class=\"kwrd\">ON<\/span> SERVER\r\n<span class=\"kwrd\">STATE<\/span>=STOP;\r\n<span class=\"kwrd\">GO<\/span>\r\n\r\n<span class=\"rem\">-- Start the Event Session Again<\/span>\r\n<span class=\"kwrd\">ALTER<\/span> EVENT <span class=\"kwrd\">SESSION<\/span> [SQLskills_TrackPageSplits]\r\n<span class=\"kwrd\">ON<\/span> SERVER\r\n<span class=\"kwrd\">STATE<\/span>=<span class=\"kwrd\">START<\/span>;\r\nGO<\/pre>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<style type=\"text\/css\">\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/style>\n<\/blockquote>\n<p>With the reset performed we can again start up our workload generation and begin monitoring the effect of the FillFactor specifications on the indexes with our code.&#160; After another 2 minute period, the following splits were noted.<\/p>\n<p><a href=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/7f3acdaf\/image.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/259cb0fb\/image_thumb.png\" width=\"442\" height=\"87\" \/><\/a><\/p>\n<p>With this information we can go back and again attempt to tune our FillFactor values for the worst splitting indexes and rinse\/repeat until we determine the best FillFactor for each of the indexes to minimize splits.&#160; This is an incredibly powerful tool for the DBA moving into SQL Server 2012, and will definitely change how we perform index fragmentation analysis and troubleshoot problems with excessive log generation in SQL Server 2012 onwards.<\/p>\n<p>Cheers!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just over a year ago I blogged about the enhancements that were made to the sqlserver.page_split Event in SQL Server 2012 to make it easier to identify what the splitting object was and the type of split that was being performed.&#160; Sadly what I discovered writing that post was that even with the extra information [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19,23,27,39,40],"tags":[],"class_list":["post-503","post","type-post","status-publish","format-standard","hentry","category-database-administration","category-extended-events","category-internals","category-sql-server-2012","category-sql-server-denali"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time! - Jonathan Kehayias<\/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:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time! - Jonathan Kehayias\" \/>\n<meta property=\"og:description\" content=\"Just over a year ago I blogged about the enhancements that were made to the sqlserver.page_split Event in SQL Server 2012 to make it easier to identify what the splitting object was and the type of split that was being performed.&#160; Sadly what I discovered writing that post was that even with the extra information [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/\" \/>\n<meta property=\"og:site_name\" content=\"Jonathan Kehayias\" \/>\n<meta property=\"article:published_time\" content=\"2011-12-08T21:17:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-04-13T18:41:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png\" \/>\n<meta name=\"author\" content=\"Jonathan Kehayias\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jonathan Kehayias\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/\"},\"author\":{\"name\":\"Jonathan Kehayias\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#\\\/schema\\\/person\\\/01c10d94f3648654ef706d5e6305f69c\"},\"headline\":\"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time!\",\"datePublished\":\"2011-12-08T21:17:00+00:00\",\"dateModified\":\"2017-04-13T18:41:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/\"},\"wordCount\":925,\"commentCount\":24,\"image\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windows-live-writer\\\/0967e61de4e9\\\/278d5bf9\\\/image_thumb.png\",\"articleSection\":[\"Database Administration\",\"Extended Events\",\"Internals\",\"SQL Server 2012\",\"SQL Server Denali\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/\",\"url\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/\",\"name\":\"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time! - Jonathan Kehayias\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windows-live-writer\\\/0967e61de4e9\\\/278d5bf9\\\/image_thumb.png\",\"datePublished\":\"2011-12-08T21:17:00+00:00\",\"dateModified\":\"2017-04-13T18:41:27+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#\\\/schema\\\/person\\\/01c10d94f3648654ef706d5e6305f69c\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windows-live-writer\\\/0967e61de4e9\\\/278d5bf9\\\/image_thumb.png\",\"contentUrl\":\"https:\\\/\\\/www.SQLskills.com\\\/blogs\\\/jonathan\\\/wp-content\\\/uploads\\\/windows-live-writer\\\/0967e61de4e9\\\/278d5bf9\\\/image_thumb.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Database Administration\",\"item\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/category\\\/database-administration\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#website\",\"url\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/\",\"name\":\"Jonathan Kehayias - The Rambling DBA\",\"description\":\"The Rambling DBA\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.sqlskills.com\\\/blogs\\\/jonathan\\\/#\\\/schema\\\/person\\\/01c10d94f3648654ef706d5e6305f69c\",\"name\":\"Jonathan Kehayias\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g\",\"caption\":\"Jonathan Kehayias\"},\"sameAs\":[\"http:\\\/\\\/3.209.169.194\\\/blogs\\\/jonathan\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time! - Jonathan Kehayias","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:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/","og_locale":"en_US","og_type":"article","og_title":"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time! - Jonathan Kehayias","og_description":"Just over a year ago I blogged about the enhancements that were made to the sqlserver.page_split Event in SQL Server 2012 to make it easier to identify what the splitting object was and the type of split that was being performed.&#160; Sadly what I discovered writing that post was that even with the extra information [&hellip;]","og_url":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/","og_site_name":"Jonathan Kehayias","article_published_time":"2011-12-08T21:17:00+00:00","article_modified_time":"2017-04-13T18:41:27+00:00","og_image":[{"url":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png","type":"","width":"","height":""}],"author":"Jonathan Kehayias","twitter_misc":{"Written by":"Jonathan Kehayias","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#article","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/"},"author":{"name":"Jonathan Kehayias","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#\/schema\/person\/01c10d94f3648654ef706d5e6305f69c"},"headline":"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time!","datePublished":"2011-12-08T21:17:00+00:00","dateModified":"2017-04-13T18:41:27+00:00","mainEntityOfPage":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/"},"wordCount":925,"commentCount":24,"image":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#primaryimage"},"thumbnailUrl":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png","articleSection":["Database Administration","Extended Events","Internals","SQL Server 2012","SQL Server Denali"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/","url":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/","name":"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time! - Jonathan Kehayias","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#primaryimage"},"image":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#primaryimage"},"thumbnailUrl":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png","datePublished":"2011-12-08T21:17:00+00:00","dateModified":"2017-04-13T18:41:27+00:00","author":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#\/schema\/person\/01c10d94f3648654ef706d5e6305f69c"},"breadcrumb":{"@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#primaryimage","url":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png","contentUrl":"https:\/\/www.SQLskills.com\/blogs\/jonathan\/wp-content\/uploads\/windows-live-writer\/0967e61de4e9\/278d5bf9\/image_thumb.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/tracking-problematic-pages-splits-in-sql-server-2012-extended-events-no-really-this-time\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/"},{"@type":"ListItem","position":2,"name":"Database Administration","item":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/category\/database-administration\/"},{"@type":"ListItem","position":3,"name":"Tracking Problematic Pages Splits in SQL Server 2012 Extended Events \u2013 No Really This Time!"}]},{"@type":"WebSite","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#website","url":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/","name":"Jonathan Kehayias - The Rambling DBA","description":"The Rambling DBA","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/#\/schema\/person\/01c10d94f3648654ef706d5e6305f69c","name":"Jonathan Kehayias","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/86630e27f5deecc5c393ea57fc7c3b6a068949f4fd6b5309f81de5a276f12855?s=96&d=mm&r=g","caption":"Jonathan Kehayias"},"sameAs":["http:\/\/3.209.169.194\/blogs\/jonathan"]}]}},"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/posts\/503","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/comments?post=503"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/posts\/503\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/media?parent=503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/categories?post=503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/jonathan\/wp-json\/wp\/v2\/tags?post=503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}