<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>chris moos&#039;s blog &#187; partitioning</title>
	<atom:link href="http://chrismoos.com/tag/partitioning/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrismoos.com</link>
	<description>coding my way through life</description>
	<lastBuildDate>Sun, 18 Sep 2011 19:48:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>MySQL and partitioning tables with millions of&#160;rows</title>
		<link>http://chrismoos.com/2010/01/31/mysql-partitioning-tables-with-millions-of-rows/</link>
		<comments>http://chrismoos.com/2010/01/31/mysql-partitioning-tables-with-millions-of-rows/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 19:43:58 +0000</pubDate>
		<dc:creator>Chris Moos</dc:creator>
				<category><![CDATA[moostrax]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[partitioning]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://chrismoos.com/?p=644</guid>
		<description><![CDATA[The Problem I&#8217;ve been running a mobile GPS tracking service, MoosTrax (formerly BlackBerry Tracker), for a few years and have encountered a large amount of data in the process. A user&#8217;s phone sends its location to the server and it is stored in a MySQL database. Each &#8220;location&#8221; entry is stored as a single row [...]]]></description>
			<content:encoded><![CDATA[<h2>The Problem</h2>
<p>I&#8217;ve been running a mobile GPS tracking service, <a href="http://moostrax.com">MoosTrax</a> (formerly BlackBerry Tracker), for a few years and have encountered a large amount of data in the process.</p>
<p>A user&#8217;s phone sends its location to the server and it is stored in a MySQL database. Each &#8220;location&#8221; entry is stored as a single row in a table.</p>
<p>Right now there are approximately 12 million rows in the location table, and things are getting slow now, as a full table scan can take ~3-4 minutes on my limited hardware. This means that if a user is pulling a location from history it could potentially block all other users (as the table is locked) access to the site until the query is complete.</p>
<h2>Partitioning</h2>
<p>Partitioning allows you to store parts of your table in their own logical space. With partitioning, you want to divide up your rows based on how you access them. If you partition your rows and you are still hitting all the partitions, it does you no good. The goal is that when you query, you will only have to look at a subset of the data to get a result, and not the whole table.</p>
<p>There are various ways in MySQL to partition a database, such as:</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning-range.html">RANGE</a> &#8211; rows are partitioned based on the range of a column (i.e date, 2006-2007, 2007-20008, etc,.) </li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning-hash.html">HASH</a> &#8211; hashes a column and depending on the result of the hash, has a different partition</li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning-list.html">LIST</a>, <a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning-key.html">KEY</a></li>
</ul>
<p>Choosing the partition type is important, so I looked at how my application looks up a user&#8217;s location.</p>
<p><strong>Getting a user&#8217;s current location</strong></p>
<div class="codecolorer-container ruby blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Location.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:device_id <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@device</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;date_added desc&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">6</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></td></tr></tbody></table></div>
<p><span id="more-644"></span></p>
<p><strong>Getting a users&#8217;s location history</strong></p>
<div class="codecolorer-container ruby blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Location.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:date_added <span style="color:#006600; font-weight:bold;">=&gt;</span> startdate.<span style="color:#9900CC;">utc</span>..<span style="color:#9900CC;">enddate</span>.<span style="color:#9900CC;">utc</span>, <span style="color:#ff3333; font-weight:bold;">:device_id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@device</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;date_added desc&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">500</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></td></tr></tbody></table></div>
<p>At first, I thought about RANGE partitioning by date, and while I am using the date in my queries, it is very common for a query to have a very large date range, and that means it could easily span all partitions.</p>
<p>After a second look, it seemed that <em>device_id</em> might be the best, using the HASH partitioning type. </p>
<p>This means that all the locations would be partitioned equally by their device_id. This is great because MoosTrax is only looking at one device at a time, history or live tracking, and doesn&#8217;t aggregate the locations across devices or users. </p>
<h3>Preparing to partition</h3>
<p>First, to partition a table the column you want to partition by must be part of the primary key. I only had &#8220;id&#8221; in my primary key, so I modified it to include my partitioning column, <em>device_id</em>.</p>
<h4>Drop the Primary Key</h4>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> location <span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span></div></td></tr></tbody></table></div>
<h3>Partition the table</h3>
<p>Now we are going to add our new primary key, and tell MySQL to partition, with HASH, by device_id. We also specify the option, <em>partitions</em>, to tell MySQL how many partitions we want it to use. I believe the limit is 1024.</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> location <br />
<span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span> device_id<span style="color: #66cc66;">&#41;</span><br />
partition <span style="color: #993333; font-weight: bold;">BY</span> HASH<span style="color: #66cc66;">&#40;</span>device_id<span style="color: #66cc66;">&#41;</span><br />
partitions <span style="color: #cc66cc;">200</span></div></td></tr></tbody></table></div>
<p>FYI: Running the above may take a while depending on the size of your table.</p>
<h3>Does it work?</h3>
<p>MySQL has a command that we can run, <em>explain partitions</em>, that will let us specify a query, and MySQL will tell us if and how it is using partitioning to get the result.</p>
<p>Because we partitioned by device_id, let&#8217;s try a simple select with device_id in the where clause.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #000000; font-weight: bold;">&gt;</span> explain partitions <span style="color: #000000; font-weight: bold;">select</span> <span style="color: #000000; font-weight: bold;">*</span> from location where device_id = <span style="color: #000000;">1</span>;<br />
+----+-------------+----------+------------+------+---------------+-----------+---------+-------+------+-------+<br />
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">id</span> <span style="color: #000000; font-weight: bold;">|</span> select_type <span style="color: #000000; font-weight: bold;">|</span> table &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> partitions <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #7a0874; font-weight: bold;">type</span> <span style="color: #000000; font-weight: bold;">|</span> possible_keys <span style="color: #000000; font-weight: bold;">|</span> key &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> key_len <span style="color: #000000; font-weight: bold;">|</span> ref &nbsp; <span style="color: #000000; font-weight: bold;">|</span> rows <span style="color: #000000; font-weight: bold;">|</span> Extra <span style="color: #000000; font-weight: bold;">|</span><br />
+----+-------------+----------+------------+------+---------------+-----------+---------+-------+------+-------+<br />
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1</span> &nbsp;<span style="color: #000000; font-weight: bold;">|</span> SIMPLE &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> location <span style="color: #000000; font-weight: bold;">|</span> p1 &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> ref &nbsp;<span style="color: #000000; font-weight: bold;">|</span> device_id &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> device_id <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">4</span> &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> const <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1</span> &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span><br />
+----+-------------+----------+------------+------+---------------+-----------+---------+-------+------+-------+<br />
<span style="color: #000000;">1</span> rows <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0.14</span> sec<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<br />
mysql<span style="color: #000000; font-weight: bold;">&gt;</span></div></td></tr></tbody></table></div>
<p>If you look at the result of the explain, you can see that MySQL only needs to use partition <em>p1</em> to find our result..this is great! There are way less rows in the partition than in the whole table. </p>
<p>Now let&#8217;s try another query, that won&#8217;t use our partitioning column.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #000000; font-weight: bold;">&gt;</span> explain partitions <span style="color: #000000; font-weight: bold;">select</span> <span style="color: #000000; font-weight: bold;">*</span> from location where date_added <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'2009-10-10'</span>;<br />
+----+-------------+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+---------------+------+---------+------+---------+-------------+<br />
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">id</span> <span style="color: #000000; font-weight: bold;">|</span> select_type <span style="color: #000000; font-weight: bold;">|</span> table &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> partitions &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #7a0874; font-weight: bold;">type</span> <span style="color: #000000; font-weight: bold;">|</span> possible_keys <span style="color: #000000; font-weight: bold;">|</span> key &nbsp;<span style="color: #000000; font-weight: bold;">|</span> key_len <span style="color: #000000; font-weight: bold;">|</span> ref &nbsp;<span style="color: #000000; font-weight: bold;">|</span> rows &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> Extra &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span><br />
+----+-------------+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+---------------+------+---------+------+---------+-------------+<br />
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1</span> &nbsp;<span style="color: #000000; font-weight: bold;">|</span> SIMPLE &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> location <span style="color: #000000; font-weight: bold;">|</span> p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94,p95,p96,p97,p98,p99,p100,p101,p102,p103,p104,p105,p106,p107,p108,p109,p110,p111,p112,p113,p114,p115,p116,p117,p118,p119,p120,p121,p122,p123,p124,p125,p126,p127,p128,p129,p130,p131,p132,p133,p134,p135,p136,p137,p138,p139,p140,p141,p142,p143,p144,p145,p146,p147,p148,p149,p150,p151,p152,p153,p154,p155,p156,p157,p158,p159,p160,p161,p162,p163,p164,p165,p166,p167,p168,p169,p170,p171,p172,p173,p174,p175,p176,p177,p178,p179,p180,p181,p182,p183,p184,p185,p186,p187,p188,p189,p190,p191,p192,p193,p194,p195,p196,p197,p198,p199 <span style="color: #000000; font-weight: bold;">|</span> ALL &nbsp;<span style="color: #000000; font-weight: bold;">|</span> date_added &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> NULL <span style="color: #000000; font-weight: bold;">|</span> NULL &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> NULL <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">12641367</span> <span style="color: #000000; font-weight: bold;">|</span> Using where <span style="color: #000000; font-weight: bold;">|</span><br />
+----+-------------+----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+---------------+------+---------+------+---------+-------------+<br />
<span style="color: #000000;">1</span> rows <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1.81</span> sec<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<br />
mysql<span style="color: #000000; font-weight: bold;">&gt;</span></div></td></tr></tbody></table></div>
<p>As you can see, MySQL would need to go through all 200 partitions to get the result. Fortunately, MoosTrax doesn&#8217;t use a query like that, as the device_id is always available. Therefore, if I am searching by date, I will also specify the device_id as well, so that MySQL will use the partition.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #000000; font-weight: bold;">&gt;</span> explain partitions <span style="color: #000000; font-weight: bold;">select</span> <span style="color: #000000; font-weight: bold;">*</span> from location where date_added <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'2009-10-10'</span> and device_id = <span style="color: #000000;">1</span>;<br />
+----+-------------+----------+------------+------+----------------------+-----------+---------+-------+------+-------------+<br />
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">id</span> <span style="color: #000000; font-weight: bold;">|</span> select_type <span style="color: #000000; font-weight: bold;">|</span> table &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> partitions <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #7a0874; font-weight: bold;">type</span> <span style="color: #000000; font-weight: bold;">|</span> possible_keys &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> key &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> key_len <span style="color: #000000; font-weight: bold;">|</span> ref &nbsp; <span style="color: #000000; font-weight: bold;">|</span> rows <span style="color: #000000; font-weight: bold;">|</span> Extra &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span><br />
+----+-------------+----------+------------+------+----------------------+-----------+---------+-------+------+-------------+<br />
<span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1</span> &nbsp;<span style="color: #000000; font-weight: bold;">|</span> SIMPLE &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> location <span style="color: #000000; font-weight: bold;">|</span> p1 &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> ref &nbsp;<span style="color: #000000; font-weight: bold;">|</span> device_id,date_added <span style="color: #000000; font-weight: bold;">|</span> device_id <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">4</span> &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">|</span> const <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1</span> &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">|</span> Using where <span style="color: #000000; font-weight: bold;">|</span><br />
+----+-------------+----------+------------+------+----------------------+-----------+---------+-------+------+-------------+<br />
<span style="color: #000000;">1</span> rows <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">set</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0.11</span> sec<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<br />
mysql<span style="color: #000000; font-weight: bold;">&gt;</span></div></td></tr></tbody></table></div>
<p>That&#8217;s better. Now its using our partitions correctly.</p>
<p>As long as you always <strong>use your partitioning column in your query</strong>, you will be able to take advantage of the partitioning.</p>
<h2>The Result</h2>
<p>After switching to partitioning, many queries are running much much faster than before. I couldn&#8217;t be happier.</p>
<p>If you want to read more about MySQL partitioning, check out the <a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning.html">manual</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://chrismoos.com/2010/01/31/mysql-partitioning-tables-with-millions-of-rows/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

