{"id":825,"date":"2010-10-21T07:36:37","date_gmt":"2010-10-21T01:36:37","guid":{"rendered":"http:\/\/techsatwork.com\/blog\/?p=825"},"modified":"2016-01-07T11:31:08","modified_gmt":"2016-01-07T05:31:08","slug":"benefits-of-data-partitioning-and-mdc","status":"publish","type":"post","link":"https:\/\/techsatwork.com\/?p=825","title":{"rendered":"Benefits of Data Partitioning and MDC !"},"content":{"rendered":"<p>Data Partitioning is a way to scale your database structure to improve performance and manageability. \u00c2\u00a0Data Partitioning is a method of \u00c2\u00a0logically and physically segregating data within tables and indexes so that queries can access them individually or concurrently. Pretty much every commercially available RDBMS has data partitioning as one of its features and they come in different varieties too.<br \/>\nIBM has been pioneering data partitioning for years. \u00c2\u00a0DB2 on mainframe has been enjoying partitioning for many years and it rocks ! \u00c2\u00a0 DB2 UDB started with DPF \u00c2\u00a0(Distributed Partition Facility) on its DB2 EEE days. \u00c2\u00a0The concept was to distribute the instance across multiple nodes (logical or physical) so that the database workload can take advantage of non-shared resources across the nodes.<\/p>\n<p>I had written <a href=\"https:\/\/techsatwork.com\/blog\/?p=191\" target=\"_blank\">an article <\/a>in 2009 that explained a bit about table partitoning, so I am not going to repeat it.\u00c2\u00a0 Today we will look into how\u00c2\u00a0<a style=\"font-family: Georgia, 'Bitstream Charter', serif; color: #ff4b33; line-height: 1.5;\" href=\"http:\/\/publib.boulder.ibm.com\/infocenter\/db2luw\/v9r7\/topic\/com.ibm.db2.luw.admin.partition.doc\/doc\/c0021560.html\" target=\"_blank\">table partitioning<\/a> and <a href=\"http:\/\/publib.boulder.ibm.com\/infocenter\/db2luw\/v9r7\/topic\/com.ibm.db2.luw.admin.partition.doc\/doc\/c0007201.html\" target=\"_blank\">multi-dimensional cluster<\/a> can improve your performance. \u00c2\u00a0I did a three part exercise to compare the outcome. \u00c2\u00a0I am going to show you three different scenarios that illustrates the benefits of\u00c2\u00a0table partitioning and multi-dimensional custer.<\/p>\n<p>The first scenario is with a regular table, the second scenario is with a partitioned table and the third scenario is a partitioned table with MDC columns.<br \/>\nThe sql we are going to run all the three scenarios is :<br \/>\nselect customer_id from tableA where year =&#8217;2010&#8242; \u00c2\u00a0and state = &#8216;TX&#8217; and \u00c2\u00a0order_date &lt;&gt; ship_date ;<\/p>\n<p><strong>Scenario 1:<\/strong><br \/>\nLets just use a table with just 5 columns with 14 millions rows :<br \/>\nCUSTOMER_ID \u00c2\u00a0INT<br \/>\nORDER_ID \u00c2\u00a0 \u00c2\u00a0 INT<br \/>\nORDER_DATE \u00c2\u00a0DATE<br \/>\nSHIP_DATE DATE<br \/>\nYEAR INT<br \/>\nSTATE \u00c2\u00a0 CHAR(2)<\/p>\n<p>The table has an index of YEAR \u00c2\u00a0and STATE .<\/p>\n<p>Result : \u00c2\u00a0 When I ran the query, I got the following results :<br \/>\n<span style=\"font-size: 13px; line-height: 19px;\">Estimated Cost = 90865.046875<\/span><\/p>\n<div id=\"_mcePaste\">( \u00c2\u00a0 \u00c2\u00a02) Access Table Name = RAJU.TABLEA = 3,4<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0Index Scan: \u00c2\u00a0Name =\u00c2\u00a0RAJU.TABLEA_X1 \u00c2\u00a0ID = 1<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0Regular Index (Not Clustered)<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0Index Columns:<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: YEAR (Ascending)<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: STATE (Ascending)<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0#Columns = 1<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0#Key Columns = 2<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0Start Key: Inclusive Value<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: 2008<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: &#8216;TX&#8217;<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0Stop Key: Inclusive Value<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: 2008<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: &#8216;TX&#8217;<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0Data Prefetch: Eligible 11980<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0Index Prefetch: Eligible 11980<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0Isolation Level: Uncommitted Read<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0Lock Intents<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0Table: Intent None<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0Row \u00c2\u00a0: None<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0Sargable Predicate(s)<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0#Predicates = 1<\/div>\n<div id=\"_mcePaste\">( \u00c2\u00a0 \u00c2\u00a02) | \u00c2\u00a0| \u00c2\u00a0Return Data to Application<\/div>\n<div id=\"_mcePaste\">| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0#Columns = 1<\/div>\n<div id=\"_mcePaste\">( \u00c2\u00a0 \u00c2\u00a01) Return Data Completion<\/div>\n<div id=\"_mcePaste\">Total Time: \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a026.740789 seconds<\/div>\n<div><span style=\"line-height: 24px; font-size: 16px;\"><br \/>\n<strong>Scenario 2 :<\/strong><br \/>\nLets use the same table with YEAR column partitioned by each year on the data, in my case it was 5 partition.<br \/>\n<\/span><\/div>\n<div><span style=\"line-height: 24px; font-size: 16px;\">Result :<br \/>\n<\/span><\/div>\n<div>\n<div>Estimated Cost = 1841.140381<\/div>\n<div>( \u00c2\u00a0 \u00c2\u00a02) Access Table Name =\u00c2\u00a0RAJU.TABLEA\u00c2\u00a0 ID = -6,-32767<\/div>\n<div>| \u00c2\u00a0Index Scan: \u00c2\u00a0Name =\u00c2\u00a0RAJU.TABLEA_X1 \u00c2\u00a0ID = 1<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Regular Index (Not Clustered)<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Index Columns:<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: YEAR (Ascending)<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: STATE (Ascending)<\/div>\n<div>| \u00c2\u00a0#Columns = 1<\/div>\n<div>| \u00c2\u00a0Data-Partitioned Table<\/div>\n<div>| \u00c2\u00a0Data Partition Elimination Info:<\/div>\n<div>| \u00c2\u00a0Active Data Partitions: 0-11<\/div>\n<div>| \u00c2\u00a0#Key Columns = 2<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Start Key: Inclusive Value<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: 2008<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: &#8216;TX&#8217;<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Stop Key: Inclusive Value<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: 2008<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: &#8216;TX&#8217;<\/div>\n<div>| \u00c2\u00a0Data Prefetch: Eligible 1563<\/div>\n<div>| \u00c2\u00a0Index Prefetch: Eligible 1563<\/div>\n<div>| \u00c2\u00a0Isolation Level: Uncommitted Read<\/div>\n<div>| \u00c2\u00a0Lock Intents<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Table: Intent None<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Row \u00c2\u00a0: None<\/div>\n<div>| \u00c2\u00a0Sargable Predicate(s)<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0#Predicates = 1<\/div>\n<div>( \u00c2\u00a0 \u00c2\u00a02) | \u00c2\u00a0| \u00c2\u00a0Return Data to Application<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0#Columns = 1<\/div>\n<div>( \u00c2\u00a0 \u00c2\u00a01) Return Data Completion<\/div>\n<div>Total Time: \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a010.908611 seconds<\/div>\n<\/div>\n<div><span style=\"line-height: 24px; font-size: 16px;\"><br \/>\n<strong>Scenario 3 :<\/strong> <br style=\"font-family: Georgia, 'Bitstream Charter', serif; color: #444444; line-height: 1.5;\" \/>Lets use the same table with YEAR column partitioned by each year on the data, and have it organized by Year and STATE . This means the table has a MDC of YEAR and STATE and also partitioned by YEAR.<\/p>\n<p>Result :<\/p>\n<p><\/span><\/div>\n<div>\n<div>Estimated Cost = 1650.786011<\/div>\n<div>( \u00c2\u00a0 \u00c2\u00a02) Access Table Name =\u00c2\u00a0RAJU.TABLEA\u00c2\u00a0 ID = -6,-32768<\/div>\n<div>| \u00c2\u00a0Index Scan: \u00c2\u00a0Name = SYSIBM.SQL101019170136940 \u00c2\u00a0ID = 1<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Composite Block Index<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Index Columns:<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: YEAR (Ascending)<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: STATE (Ascending)<\/div>\n<div>| \u00c2\u00a0#Columns = 1<\/div>\n<div>| \u00c2\u00a0Clustered by Dimension for Block Index Access<\/div>\n<div>| \u00c2\u00a0Data-Partitioned Table<\/div>\n<div>| \u00c2\u00a0Data Partition Elimination Info:<\/div>\n<div>| \u00c2\u00a0Active Data Partitions: 0-11<\/div>\n<div>| \u00c2\u00a0#Key Columns = 2<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Start Key: Inclusive Value<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: 2008<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: &#8216;TX&#8217;<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Stop Key: Inclusive Value<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a01: 2008<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a02: &#8216;TX&#8217;<\/div>\n<div>| \u00c2\u00a0Data Prefetch: None<\/div>\n<div>| \u00c2\u00a0Index Prefetch: None<\/div>\n<div>| \u00c2\u00a0Isolation Level: Uncommitted Read<\/div>\n<div>| \u00c2\u00a0Lock Intents<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Table: Intent None<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Block: None<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0Row \u00c2\u00a0: None<\/div>\n<div>| \u00c2\u00a0Sargable Predicate(s)<\/div>\n<div>( \u00c2\u00a0 \u00c2\u00a02) | \u00c2\u00a0| \u00c2\u00a0Return Data to Application<\/div>\n<div>| \u00c2\u00a0| \u00c2\u00a0| \u00c2\u00a0#Columns = 1<\/div>\n<div>( \u00c2\u00a0 \u00c2\u00a01) Return Data Completion<\/div>\n<div>End of section<\/div>\n<div>Total Time: \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 \u00c2\u00a0 1.147453 seconds<\/div>\n<\/div>\n<div>\n<p style=\"font-family: Georgia, 'Bitstream Charter', serif; color: #444444; line-height: 1.5; font-size: 16px; margin-bottom: 24px;\">\n<p style=\"font-family: Georgia, 'Bitstream Charter', serif; color: #444444; line-height: 1.5; font-size: 16px; margin-bottom: 24px;\">From this you can clearly see how efficient the combination of partitioned and MDC is. \u00c2\u00a0Db2 is able to do partition elimination and access the data by block index.<br \/>\nInorder to partition and create MDC, you need to know your data and how the applications access the data. \u00c2\u00a0One added benefit of MDC is that DB2 will also keep the table organized meaning, you will never have to reorg the table. \u00c2\u00a0Table Partitioning and MDC \u00c2\u00a0are only available in <a href=\"https:\/\/techsatwork.com\/blog\/wp-content\/uploads\/2010\/10\/db2editioncomparion.png\" target=\"_blank\">Enterprise Edition and up<\/a> .<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Data Partitioning is a way to scale your database structure to improve performance and manageability. \u00c2\u00a0Data Partitioning is a method of \u00c2\u00a0logically and physically segregating data within tables and indexes so that queries can access them individually or concurrently. Pretty much every commercially available RDBMS has data partitioning as one of its features and they [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","site-transparent-header":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[303,3,358],"tags":[439,430,943,433,436,434,435,437,98,438,432,431],"class_list":["post-825","post","type-post","status-publish","format-standard","hentry","category-database","category-db2","category-how-to","tag-block-index","tag-database-partition","tag-db2","tag-db2-database-partition","tag-dpf","tag-mdc","tag-multi-dimensional-cluster","tag-organize-by","tag-partition","tag-partition-elimination","tag-partitioning","tag-table-partition"],"_links":{"self":[{"href":"https:\/\/techsatwork.com\/index.php?rest_route=\/wp\/v2\/posts\/825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/techsatwork.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techsatwork.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techsatwork.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/techsatwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=825"}],"version-history":[{"count":13,"href":"https:\/\/techsatwork.com\/index.php?rest_route=\/wp\/v2\/posts\/825\/revisions"}],"predecessor-version":[{"id":1511,"href":"https:\/\/techsatwork.com\/index.php?rest_route=\/wp\/v2\/posts\/825\/revisions\/1511"}],"wp:attachment":[{"href":"https:\/\/techsatwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techsatwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techsatwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}